poly_int: fold_indirect_ref_1
authorRichard Sandiford <richard.sandiford@linaro.org>
Wed, 3 Jan 2018 07:17:12 +0000 (07:17 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 3 Jan 2018 07:17:12 +0000 (07:17 +0000)
This patch makes fold_indirect_ref_1 handle polynomial offsets in
a POINTER_PLUS_EXPR.  The specific reason for doing this now is
to handle:

    (tree_to_uhwi (part_width) / BITS_PER_UNIT
     * TYPE_VECTOR_SUBPARTS (op00type));

when TYPE_VECTOR_SUBPARTS becomes a poly_int.

2018-01-03  Richard Sandiford  <richard.sandiford@linaro.org>
    Alan Hayward  <alan.hayward@arm.com>
    David Sherwood  <david.sherwood@arm.com>

gcc/
* fold-const.c (fold_indirect_ref_1): Handle polynomial offsets
in a POINTER_PLUS_EXPR.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r256146

gcc/ChangeLog
gcc/fold-const.c

index aede16d..2899883 100644 (file)
@@ -2,6 +2,13 @@
            Alan Hayward  <alan.hayward@arm.com>
            David Sherwood  <david.sherwood@arm.com>
 
+       * fold-const.c (fold_indirect_ref_1): Handle polynomial offsets
+       in a POINTER_PLUS_EXPR.
+
+2018-01-03  Richard Sandiford  <richard.sandiford@linaro.org>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
+
        * omp-simd-clone.c (simd_clone_subparts): New function.
        (simd_clone_init_simd_arrays): Use it instead of TYPE_VECTOR_SUBPARTS.
        (ipa_simd_modify_function_body): Likewise.
index f28970b..e2e4600 100644 (file)
@@ -14049,6 +14049,7 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0)
 {
   tree sub = op0;
   tree subtype;
+  poly_uint64 const_op01;
 
   STRIP_NOPS (sub);
   subtype = TREE_TYPE (sub);
@@ -14103,7 +14104,7 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0)
     }
 
   if (TREE_CODE (sub) == POINTER_PLUS_EXPR
-      && TREE_CODE (TREE_OPERAND (sub, 1)) == INTEGER_CST)
+      && poly_int_tree_p (TREE_OPERAND (sub, 1), &const_op01))
     {
       tree op00 = TREE_OPERAND (sub, 0);
       tree op01 = TREE_OPERAND (sub, 1);
@@ -14120,15 +14121,12 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0)
              && type == TREE_TYPE (op00type))
            {
              tree part_width = TYPE_SIZE (type);
-             unsigned HOST_WIDE_INT max_offset
+             poly_uint64 max_offset
                = (tree_to_uhwi (part_width) / BITS_PER_UNIT
                   * TYPE_VECTOR_SUBPARTS (op00type));
-             if (tree_int_cst_sign_bit (op01) == 0
-                 && compare_tree_int (op01, max_offset) == -1)
+             if (known_lt (const_op01, max_offset))
                {
-                 unsigned HOST_WIDE_INT offset = tree_to_uhwi (op01);
-                 unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT;
-                 tree index = bitsize_int (indexi);
+                 tree index = bitsize_int (const_op01 * BITS_PER_UNIT);
                  return fold_build3_loc (loc,
                                          BIT_FIELD_REF, type, op00,
                                          part_width, index);
@@ -14138,8 +14136,8 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0)
          else if (TREE_CODE (op00type) == COMPLEX_TYPE
                   && type == TREE_TYPE (op00type))
            {
-             tree size = TYPE_SIZE_UNIT (type);
-             if (tree_int_cst_equal (size, op01))
+             if (known_eq (wi::to_poly_offset (TYPE_SIZE_UNIT (type)),
+                           const_op01))
                return fold_build1_loc (loc, IMAGPART_EXPR, type, op00);
            }
          /* ((foo *)&fooarray)[1] => fooarray[1] */