* [PATCH] Fix PR69047
@ 2016-08-26 12:31 Richard Biener
2016-08-29 9:22 ` Andreas Schwab
0 siblings, 1 reply; 3+ messages in thread
From: Richard Biener @ 2016-08-26 12:31 UTC (permalink / raw)
To: gcc-patches
The following fixes PR69047, update-address-taken can use the same
trick as VN and re-write MEM[&d] into SSA when the size of the MEM
and the size of d do not match by using a BIT_FIELD_REF.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.
The patch contains a workaround for PR77390.
Richard.
2016-08-26 Richard Biener <rguenther@suse.de>
PR tree-optimization/69047
* tree-ssa.c (maybe_rewrite_mem_ref_base): Handle general bitfield
extracts similar to what FRE does.
(non_rewritable_mem_ref_base): Likewise.
* gcc.dg/pr69047.c: New testcase.
Index: gcc/tree-ssa.c
===================================================================
--- gcc/tree-ssa.c (revision 239752)
+++ gcc/tree-ssa.c (working copy)
@@ -1292,7 +1292,9 @@ maybe_rewrite_mem_ref_base (tree *tp, bi
&& (sym = TREE_OPERAND (TREE_OPERAND (*tp, 0), 0))
&& DECL_P (sym)
&& !TREE_ADDRESSABLE (sym)
- && bitmap_bit_p (suitable_for_renaming, DECL_UID (sym)))
+ && bitmap_bit_p (suitable_for_renaming, DECL_UID (sym))
+ && is_gimple_reg_type (TREE_TYPE (*tp))
+ && ! VOID_TYPE_P (TREE_TYPE (*tp)))
{
if (TREE_CODE (TREE_TYPE (sym)) == VECTOR_TYPE
&& useless_type_conversion_p (TREE_TYPE (*tp),
@@ -1314,7 +1316,8 @@ maybe_rewrite_mem_ref_base (tree *tp, bi
? REALPART_EXPR : IMAGPART_EXPR,
TREE_TYPE (*tp), sym);
}
- else if (integer_zerop (TREE_OPERAND (*tp, 1)))
+ else if (integer_zerop (TREE_OPERAND (*tp, 1))
+ && DECL_SIZE (sym) == TYPE_SIZE (TREE_TYPE (*tp)))
{
if (!useless_type_conversion_p (TREE_TYPE (*tp),
TREE_TYPE (sym)))
@@ -1323,6 +1326,24 @@ maybe_rewrite_mem_ref_base (tree *tp, bi
else
*tp = sym;
}
+ else if (DECL_SIZE (sym)
+ && TREE_CODE (DECL_SIZE (sym)) == INTEGER_CST
+ && mem_ref_offset (*tp) >= 0
+ && wi::leu_p (mem_ref_offset (*tp)
+ + wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (*tp))),
+ wi::to_offset (DECL_SIZE_UNIT (sym)))
+ && (! INTEGRAL_TYPE_P (TREE_TYPE (*tp))
+ || (wi::to_offset (TYPE_SIZE (TREE_TYPE (*tp)))
+ == TYPE_PRECISION (TREE_TYPE (*tp))))
+ && wi::umod_trunc (wi::to_offset (TYPE_SIZE (TREE_TYPE (*tp))),
+ BITS_PER_UNIT) == 0)
+ {
+ *tp = build3 (BIT_FIELD_REF, TREE_TYPE (*tp), sym,
+ TYPE_SIZE (TREE_TYPE (*tp)),
+ wide_int_to_tree (bitsizetype,
+ mem_ref_offset (*tp)
+ << LOG2_BITS_PER_UNIT));
+ }
}
}
@@ -1352,6 +1373,11 @@ non_rewritable_mem_ref_base (tree ref)
&& TREE_CODE (TREE_OPERAND (base, 0)) == ADDR_EXPR)
{
tree decl = TREE_OPERAND (TREE_OPERAND (base, 0), 0);
+ if (! DECL_P (decl))
+ return NULL_TREE;
+ if (! is_gimple_reg_type (TREE_TYPE (base))
+ || VOID_TYPE_P (TREE_TYPE (base)))
+ return decl;
if ((TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE
|| TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE)
&& useless_type_conversion_p (TREE_TYPE (base),
@@ -1362,12 +1388,28 @@ non_rewritable_mem_ref_base (tree ref)
&& multiple_of_p (sizetype, TREE_OPERAND (base, 1),
TYPE_SIZE_UNIT (TREE_TYPE (base))))
return NULL_TREE;
- if (DECL_P (decl)
- && (!integer_zerop (TREE_OPERAND (base, 1))
- || (DECL_SIZE (decl)
- != TYPE_SIZE (TREE_TYPE (base)))
- || TREE_THIS_VOLATILE (decl) != TREE_THIS_VOLATILE (base)))
- return decl;
+ /* For same sizes and zero offset we can use a VIEW_CONVERT_EXPR. */
+ if (integer_zerop (TREE_OPERAND (base, 1))
+ && DECL_SIZE (decl) == TYPE_SIZE (TREE_TYPE (base)))
+ return NULL_TREE;
+ /* For integral typed extracts we can use a BIT_FIELD_REF. */
+ if (DECL_SIZE (decl)
+ && TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST
+ && mem_ref_offset (base) >= 0
+ && wi::leu_p (mem_ref_offset (base)
+ + wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (base))),
+ wi::to_offset (DECL_SIZE_UNIT (decl)))
+ /* ??? We can't handle bitfield precision extracts without
+ either using an alternate type for the BIT_FIELD_REF and
+ then doing a conversion or possibly adjusting the offset
+ according to endianess. */
+ && (! INTEGRAL_TYPE_P (TREE_TYPE (base))
+ || (wi::to_offset (TYPE_SIZE (TREE_TYPE (base)))
+ == TYPE_PRECISION (TREE_TYPE (base))))
+ && wi::umod_trunc (wi::to_offset (TYPE_SIZE (TREE_TYPE (base))),
+ BITS_PER_UNIT) == 0)
+ return NULL_TREE;
+ return decl;
}
return NULL_TREE;
Index: gcc/testsuite/gcc.dg/pr69047.c
===================================================================
--- gcc/testsuite/gcc.dg/pr69047.c (revision 0)
+++ gcc/testsuite/gcc.dg/pr69047.c (working copy)
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-cddce1" } */
+
+__UINT8_TYPE__
+f(__UINT16_TYPE__ b)
+{
+ __UINT8_TYPE__ a;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ __builtin_memcpy(&a, &b, sizeof a);
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ __builtin_memcpy(&a, (char *)&b + sizeof a, sizeof a);
+#else
+ a = b;
+#endif
+ return a;
+}
+
+/* { dg-final { scan-tree-dump "_\[0-9\]+ = \\(\[^)\]+\\) b" "cddce1" } } */
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] Fix PR69047
2016-08-26 12:31 [PATCH] Fix PR69047 Richard Biener
@ 2016-08-29 9:22 ` Andreas Schwab
2016-08-30 9:22 ` Richard Biener
0 siblings, 1 reply; 3+ messages in thread
From: Andreas Schwab @ 2016-08-29 9:22 UTC (permalink / raw)
To: Richard Biener; +Cc: gcc-patches
On Aug 26 2016, Richard Biener <rguenther@suse.de> wrote:
> Index: gcc/testsuite/gcc.dg/pr69047.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/pr69047.c (revision 0)
> +++ gcc/testsuite/gcc.dg/pr69047.c (working copy)
> @@ -0,0 +1,18 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O -fdump-tree-cddce1" } */
> +
> +__UINT8_TYPE__
> +f(__UINT16_TYPE__ b)
> +{
> + __UINT8_TYPE__ a;
> +#if __BYTE_ORDER == __LITTLE_ENDIAN
> + __builtin_memcpy(&a, &b, sizeof a);
> +#elif __BYTE_ORDER == __BIG_ENDIAN
> + __builtin_memcpy(&a, (char *)&b + sizeof a, sizeof a);
> +#else
> + a = b;
> +#endif
> + return a;
> +}
> +
> +/* { dg-final { scan-tree-dump "_\[0-9\]+ = \\(\[^)\]+\\) b" "cddce1" } } */
>
On m68k:
FAIL: gcc.dg/pr69047.c scan-tree-dump cddce1 "_[0-9]+ = \\([^)]+\\) b"
$ cat pr69047.c.037t.cddce1
;; Function f (f, funcdef_no=0, decl_uid=1432, cgraph_uid=0, symbol_order=0)
f (short unsigned int b)
{
unsigned char a;
unsigned char _2;
<bb 2>:
_2 = BIT_FIELD_REF <b_6(D), 8, 0>;
return _2;
}
Andreas.
--
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] Fix PR69047
2016-08-29 9:22 ` Andreas Schwab
@ 2016-08-30 9:22 ` Richard Biener
0 siblings, 0 replies; 3+ messages in thread
From: Richard Biener @ 2016-08-30 9:22 UTC (permalink / raw)
To: Andreas Schwab; +Cc: gcc-patches
On Mon, 29 Aug 2016, Andreas Schwab wrote:
> On Aug 26 2016, Richard Biener <rguenther@suse.de> wrote:
>
> > Index: gcc/testsuite/gcc.dg/pr69047.c
> > ===================================================================
> > --- gcc/testsuite/gcc.dg/pr69047.c (revision 0)
> > +++ gcc/testsuite/gcc.dg/pr69047.c (working copy)
> > @@ -0,0 +1,18 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-O -fdump-tree-cddce1" } */
> > +
> > +__UINT8_TYPE__
> > +f(__UINT16_TYPE__ b)
> > +{
> > + __UINT8_TYPE__ a;
> > +#if __BYTE_ORDER == __LITTLE_ENDIAN
> > + __builtin_memcpy(&a, &b, sizeof a);
> > +#elif __BYTE_ORDER == __BIG_ENDIAN
> > + __builtin_memcpy(&a, (char *)&b + sizeof a, sizeof a);
> > +#else
> > + a = b;
> > +#endif
> > + return a;
> > +}
> > +
> > +/* { dg-final { scan-tree-dump "_\[0-9\]+ = \\(\[^)\]+\\) b" "cddce1" } } */
> >
>
> On m68k:
>
> FAIL: gcc.dg/pr69047.c scan-tree-dump cddce1 "_[0-9]+ = \\([^)]+\\) b"
>
> $ cat pr69047.c.037t.cddce1
>
> ;; Function f (f, funcdef_no=0, decl_uid=1432, cgraph_uid=0, symbol_order=0)
>
> f (short unsigned int b)
> {
> unsigned char a;
> unsigned char _2;
>
> <bb 2>:
> _2 = BIT_FIELD_REF <b_6(D), 8, 0>;
> return _2;
>
> }
>
>
> Andreas.
Ah, forgot to re-write to use GCC internal macros.
Tested on m68k, applied.
Richard.
2016-08-30 Richard Biener <rguenther@suse.de>
PR tree-optimization/69047
* gcc.dg/pr69047.c: Fix byte-order check.
Index: gcc/testsuite/gcc.dg/pr69047.c
===================================================================
--- gcc/testsuite/gcc.dg/pr69047.c (revision 239856)
+++ gcc/testsuite/gcc.dg/pr69047.c (working copy)
@@ -5,9 +5,9 @@ __UINT8_TYPE__
f(__UINT16_TYPE__ b)
{
__UINT8_TYPE__ a;
-#if __BYTE_ORDER == __LITTLE_ENDIAN
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
__builtin_memcpy(&a, &b, sizeof a);
-#elif __BYTE_ORDER == __BIG_ENDIAN
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
__builtin_memcpy(&a, (char *)&b + sizeof a, sizeof a);
#else
a = b;
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2016-08-30 9:22 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-26 12:31 [PATCH] Fix PR69047 Richard Biener
2016-08-29 9:22 ` Andreas Schwab
2016-08-30 9:22 ` Richard Biener
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).