The following fixes PR71055.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2016-05-11  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/71055
        * tree-ssa-sccvn.c (vn_reference_lookup_3): When native-interpreting
        sth with precision not equal to access size verify we don't chop
        off bits.

        * gcc.dg/torture/pr71055.c: New testcase.

Index: gcc/tree-ssa-sccvn.c
===================================================================
*** gcc/tree-ssa-sccvn.c        (revision 236069)
--- gcc/tree-ssa-sccvn.c        (working copy)
*************** vn_reference_lookup_3 (ao_ref *ref, tree
*** 1907,1920 ****
                                    buffer, sizeof (buffer));
          if (len > 0)
            {
!             tree val = native_interpret_expr (vr->type,
                                                buffer
                                                + ((offset - offset2)
                                                   / BITS_PER_UNIT),
                                                ref->size / BITS_PER_UNIT);
              if (val)
                return vn_reference_lookup_or_insert_for_pieces
!                        (vuse, vr->set, vr->type, vr->operands, val);
            }
        }
      }
--- 1950,1983 ----
                                    buffer, sizeof (buffer));
          if (len > 0)
            {
!             tree type = vr->type;
!             /* Make sure to interpret in a type that has a range
!                covering the whole access size.  */
!             if (INTEGRAL_TYPE_P (vr->type)
!                 && ref->size != TYPE_PRECISION (vr->type))
!               type = build_nonstandard_integer_type (ref->size,
!                                                      TYPE_UNSIGNED (type));
!             tree val = native_interpret_expr (type,
                                                buffer
                                                + ((offset - offset2)
                                                   / BITS_PER_UNIT),
                                                ref->size / BITS_PER_UNIT);
+             /* If we chop off bits because the types precision doesn't
+                match the memory access size this is ok when optimizing
+                reads but not when called from the DSE code during
+                elimination.  */
+             if (val
+                 && type != vr->type)
+               {
+                 if (! int_fits_type_p (val, vr->type))
+                   val = NULL_TREE;
+                 else
+                   val = fold_convert (vr->type, val);
+               }
+ 
              if (val)
                return vn_reference_lookup_or_insert_for_pieces
!                        (vuse, vr->set, vr->type, vr->operands, val);
            }
        }
      }
Index: gcc/testsuite/gcc.dg/torture/pr71055.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr71055.c      (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr71055.c      (working copy)
***************
*** 0 ****
--- 1,18 ----
+ /* { dg-do run } */
+ 
+ extern void abort (void);
+ union U { int i; _Bool b; char c; };
+ void __attribute__((noinline,noclone))
+ foo (union U *u)
+ {
+   if (u->c != 0)
+     abort ();
+ }
+ int main()
+ {
+   union U u;
+   u.i = 10;
+   u.b = 0;
+   foo (&u);
+   return 0;
+ }

Reply via email to