The following adds some more checks to the MEM_REF -> vector BIT_FIELD_REF
rewriting and adjusts another copy with the poly-int variant.

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

Richard.

2018-02-16  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/84417
        * tree-ssa.c (non_rewritable_mem_ref_base): Properly constrain
        the MEM_REF offset when conversion to BIT_FIELD_REF is desired.
        (non_rewritable_lvalue_p): Likewise, use poly-ints.

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

Index: gcc/tree-ssa.c
===================================================================
--- gcc/tree-ssa.c      (revision 257724)
+++ gcc/tree-ssa.c      (working copy)
@@ -1434,6 +1434,7 @@ non_rewritable_mem_ref_base (tree ref)
           || TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE)
          && useless_type_conversion_p (TREE_TYPE (base),
                                        TREE_TYPE (TREE_TYPE (decl)))
+         && known_ge (mem_ref_offset (base), 0)
          && known_gt (wi::to_poly_offset (TYPE_SIZE_UNIT (TREE_TYPE (decl))),
                       mem_ref_offset (base))
          && multiple_of_p (sizetype, TREE_OPERAND (base, 1),
@@ -1516,11 +1517,11 @@ non_rewritable_lvalue_p (tree lhs)
          && TYPE_MODE (TREE_TYPE (decl)) != BLKmode
          && operand_equal_p (TYPE_SIZE_UNIT (TREE_TYPE (lhs)),
                              TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))), 0)
-         && tree_fits_uhwi_p (TREE_OPERAND (lhs, 1))
-         && tree_int_cst_lt (TREE_OPERAND (lhs, 1),
-                             TYPE_SIZE_UNIT (TREE_TYPE (decl)))
-         && (tree_to_uhwi (TREE_OPERAND (lhs, 1))
-             % tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (lhs)))) == 0)
+         && known_ge (mem_ref_offset (lhs), 0)
+         && known_gt (wi::to_poly_offset (TYPE_SIZE_UNIT (TREE_TYPE (decl))),
+                      mem_ref_offset (lhs))
+         && multiple_of_p (sizetype, TREE_OPERAND (lhs, 1),
+                           TYPE_SIZE_UNIT (TREE_TYPE (lhs))))
        return false;
     }
 
Index: gcc/testsuite/gcc.dg/torture/pr84417.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr84417.c      (nonexistent)
+++ gcc/testsuite/gcc.dg/torture/pr84417.c      (working copy)
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target int32plus } */
+
+void fn1()
+{
+  __attribute__((__vector_size__(sizeof(double)))) double x;
+  double *a = (double *)&x;
+  *a + *(a + 8446744073709551615LL);
+}

Reply via email to