Now that there is (finally :() a wrong-code testcase for the
PR54570 issue we can no longer ignore it (bah).  So the following
tries to paper over the fact that object-size sucks and disables
value-numbering of equal addresses the same before that pass
had a chance to finally look at the structure of the addresses.

To make this "fix" suck less I moved the object-size pass before
the final FRE pass runs which is after IPA inlining and the
propagation of constants and addresses.  You won't catch
any "improvements" you'd get by memory CSE opportunities that
IPA inlining exposes, but you cannot have everything here.
(IMHO object-size would should run during early optimizations)

Bootstrap / regtest pending on x86_64-unknown-linux-gnu.

Similar candidate for the 4.8 branch.

Any comments?

Thanks,
Richard.

2013-11-15  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/59125
        PR tree-optimization/54570
        * tree-ssa-sccvn.c (copy_reference_ops_from_ref): When inlining
        is not complete do not treat component-references with offset zero
        but different fields as equal.
        * passes.def (pass_all_optimizations): Move pass_object_sizes
        after the first pass_forwprop and before pass_fre.

        * gcc.dg/builtin-object-size-8.c: Un-xfail.
        * gcc.dg/builtin-object-size-14.c: New testcase.

Index: gcc/tree-ssa-sccvn.c
===================================================================
*** gcc/tree-ssa-sccvn.c        (revision 204787)
--- gcc/tree-ssa-sccvn.c        (working copy)
*************** copy_reference_ops_from_ref (tree ref, v
*** 759,765 ****
      }
  
    /* For non-calls, store the information that makes up the address.  */
! 
    while (ref)
      {
        vn_reference_op_s temp;
--- 759,765 ----
      }
  
    /* For non-calls, store the information that makes up the address.  */
!   tree orig = ref;
    while (ref)
      {
        vn_reference_op_s temp;
*************** copy_reference_ops_from_ref (tree ref, v
*** 809,815 ****
                        + tree_to_double_int (bit_offset)
                        .rshift (BITS_PER_UNIT == 8
                                   ? 3 : exact_log2 (BITS_PER_UNIT));
!                   if (off.fits_shwi ())
                      temp.off = off.low;
                  }
              }
--- 809,818 ----
                        + tree_to_double_int (bit_offset)
                        .rshift (BITS_PER_UNIT == 8
                                   ? 3 : exact_log2 (BITS_PER_UNIT));
!                   if (off.fits_shwi ()
!                       && (TREE_CODE (orig) != ADDR_EXPR
!                           || !off.is_zero ()
!                           || cfun->after_inlining))
                      temp.off = off.low;
                  }
              }
Index: gcc/passes.def
===================================================================
*** gcc/passes.def      (revision 204787)
--- gcc/passes.def      (working copy)
*************** along with GCC; see the file COPYING3.
*** 142,147 ****
--- 142,148 ----
         form if possible.  */
        NEXT_PASS (pass_phiprop);
        NEXT_PASS (pass_forwprop);
+       NEXT_PASS (pass_object_sizes);
        /* pass_build_alias is a dummy pass that ensures that we
         execute TODO_rebuild_alias at this point.  */
        NEXT_PASS (pass_build_alias);
*************** along with GCC; see the file COPYING3.
*** 185,191 ****
        NEXT_PASS (pass_dce);
        NEXT_PASS (pass_forwprop);
        NEXT_PASS (pass_phiopt);
-       NEXT_PASS (pass_object_sizes);
        NEXT_PASS (pass_strlen);
        NEXT_PASS (pass_ccp);
        /* After CCP we rewrite no longer addressed locals into SSA
--- 186,191 ----
Index: gcc/testsuite/gcc.dg/builtin-object-size-8.c
===================================================================
*** gcc/testsuite/gcc.dg/builtin-object-size-8.c        (revision 204787)
--- gcc/testsuite/gcc.dg/builtin-object-size-8.c        (working copy)
***************
*** 1,4 ****
! /* { dg-do run { xfail *-*-* } } */
  /* { dg-options "-O2" } */
  
  typedef __SIZE_TYPE__ size_t;
--- 1,4 ----
! /* { dg-do run } */
  /* { dg-options "-O2" } */
  
  typedef __SIZE_TYPE__ size_t;
Index: gcc/testsuite/gcc.dg/builtin-object-size-14.c
===================================================================
*** gcc/testsuite/gcc.dg/builtin-object-size-14.c       (revision 0)
--- gcc/testsuite/gcc.dg/builtin-object-size-14.c       (working copy)
***************
*** 0 ****
--- 1,28 ----
+ /* { dg-do run } */
+ /* { dg-options "-O2" } */
+ 
+ extern void abort (void);
+ extern char *strncpy(char *, const char *, __SIZE_TYPE__);
+ 
+ union u {
+     struct {
+       char vi[8];
+       char pi[16];
+     };
+     char all[8+16+4];
+ };
+ 
+ void __attribute__((noinline,noclone))
+ f(union u *u)
+ {
+   char vi[8+1];
+   __builtin_strncpy(vi, u->vi, sizeof(u->vi));
+   if (__builtin_object_size (u->all, 1) != -1)
+     abort ();
+ }
+ int main()
+ {
+   union u u;
+   f (&u);
+   return 0;
+ }

Reply via email to