re PR tree-optimization/77916 (ICE in verify_gimple_in_cfg: invalid (pointer) operand...
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>
Mon, 17 Oct 2016 22:08:56 +0000 (22:08 +0000)
committerWilliam Schmidt <wschmidt@gcc.gnu.org>
Mon, 17 Oct 2016 22:08:56 +0000 (22:08 +0000)
[gcc]

2016-10-17  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

PR tree-optimization/77916
* gimple-ssa-strength-reduction.c (create_add_on_incoming_edge):
Don't allow a MINUS_EXPR for pointer arithmetic for either known
or unknown strides.
(record_increment): Increments of -1 for unknown strides just use
a multiply initializer like other negative values.
(analyze_increments): Remove stopgap solution for -1 increment
applied to pointer arithmetic.

[gcc/testsuite]

2016-10-17  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

PR tree-optimization/77916
* gcc.dg/torture/pr77916.c: New.

From-SVN: r241281

gcc/ChangeLog
gcc/gimple-ssa-strength-reduction.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr77916.c [new file with mode: 0644]

index b512e4b9bbcf481df99a9d2761522edba398229d..89a03e90c51f48383b115e8d8355f4bc42cb506c 100644 (file)
@@ -1,3 +1,14 @@
+2016-10-17  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
+
+       PR tree-optimization/77916
+       * gimple-ssa-strength-reduction.c (create_add_on_incoming_edge):
+       Don't allow a MINUS_EXPR for pointer arithmetic for either known
+       or unknown strides.
+       (record_increment): Increments of -1 for unknown strides just use
+       a multiply initializer like other negative values.
+       (analyze_increments): Remove stopgap solution for -1 increment
+       applied to pointer arithmetic.
+
 2016-10-17  Yuri Rumyantsev  <ysrumyan@gmail.com>
 
        * dominance.c (dom_info::dom_info): Add new constructor for region
index 72862f851442a19e68f2578b1e7a3633ce657114..2ef5c482582abce154a6a4020e737e10e732fa3c 100644 (file)
@@ -2154,35 +2154,41 @@ create_add_on_incoming_edge (slsr_cand_t c, tree basis_name,
   basis_type = TREE_TYPE (basis_name);
   lhs = make_temp_ssa_name (basis_type, NULL, "slsr");
 
+  /* Occasionally people convert integers to pointers without a 
+     cast, leading us into trouble if we aren't careful.  */
+  enum tree_code plus_code
+    = POINTER_TYPE_P (basis_type) ? POINTER_PLUS_EXPR : PLUS_EXPR;
+
   if (known_stride)
     {
       tree bump_tree;
-      enum tree_code code = PLUS_EXPR;
+      enum tree_code code = plus_code;
       widest_int bump = increment * wi::to_widest (c->stride);
-      if (wi::neg_p (bump))
+      if (wi::neg_p (bump) && !POINTER_TYPE_P (basis_type))
        {
          code = MINUS_EXPR;
          bump = -bump;
        }
 
-      bump_tree = wide_int_to_tree (basis_type, bump);
+      tree stride_type = POINTER_TYPE_P (basis_type) ? sizetype : basis_type;
+      bump_tree = wide_int_to_tree (stride_type, bump);
       new_stmt = gimple_build_assign (lhs, code, basis_name, bump_tree);
     }
   else
     {
       int i;
-      bool negate_incr = (!address_arithmetic_p && wi::neg_p (increment));
+      bool negate_incr = !POINTER_TYPE_P (basis_type) && wi::neg_p (increment);
       i = incr_vec_index (negate_incr ? -increment : increment);
       gcc_assert (i >= 0);
 
       if (incr_vec[i].initializer)
        {
-         enum tree_code code = negate_incr ? MINUS_EXPR : PLUS_EXPR;
+         enum tree_code code = negate_incr ? MINUS_EXPR : plus_code;
          new_stmt = gimple_build_assign (lhs, code, basis_name,
                                          incr_vec[i].initializer);
        }
       else if (increment == 1)
-       new_stmt = gimple_build_assign (lhs, PLUS_EXPR, basis_name, c->stride);
+       new_stmt = gimple_build_assign (lhs, plus_code, basis_name, c->stride);
       else if (increment == -1)
        new_stmt = gimple_build_assign (lhs, MINUS_EXPR, basis_name,
                                        c->stride);
@@ -2500,12 +2506,14 @@ record_increment (slsr_cand_t c, widest_int increment, bool is_phi_adjust)
       /* Optimistically record the first occurrence of this increment
         as providing an initializer (if it does); we will revise this
         opinion later if it doesn't dominate all other occurrences.
-         Exception:  increments of -1, 0, 1 never need initializers;
-        and phi adjustments don't ever provide initializers.  */
+         Exception:  increments of 0, 1 never need initializers;
+        and phi adjustments don't ever provide initializers.  Note
+         that we only will see an increment of -1 here for pointer
+        arithmetic (otherwise we will have an initializer).  */
       if (c->kind == CAND_ADD
          && !is_phi_adjust
          && c->index == increment
-         && (increment > 1 || increment < -1)
+         && (increment > 1 || increment < 0)
          && (gimple_assign_rhs_code (c->cand_stmt) == PLUS_EXPR
              || gimple_assign_rhs_code (c->cand_stmt) == POINTER_PLUS_EXPR))
        {
@@ -2819,11 +2827,6 @@ analyze_increments (slsr_cand_t first_dep, machine_mode mode, bool speed)
                   && !POINTER_TYPE_P (first_dep->cand_type)))
        incr_vec[i].cost = COST_NEUTRAL;
 
-      /* FIXME: We don't handle pointers with a -1 increment yet.
-         They are usually unprofitable anyway.  */
-      else if (incr == -1 && POINTER_TYPE_P (first_dep->cand_type))
-       incr_vec[i].cost = COST_INFINITE;
-      
       /* FORNOW: If we need to add an initializer, give up if a cast from
         the candidate's type to its stride's type can lose precision.
         This could eventually be handled better by expressly retaining the
index 7d4a4416e49af0d0e02fef6ec246d0dd79a22c07..ddad6fc9a8925843cc04b9bcab4a59e78eb00411 100644 (file)
@@ -1,3 +1,8 @@
+2016-10-17  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
+
+       PR tree-optimization/77916
+       * gcc.dg/torture/pr77916.c: New.
+
 2016-10-17  Steven G. Kargl  <kargl@gcc.gnu.org>
 
        PR fortran/77978
diff --git a/gcc/testsuite/gcc.dg/torture/pr77916.c b/gcc/testsuite/gcc.dg/torture/pr77916.c
new file mode 100644 (file)
index 0000000..f29f099
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -Wno-int-conversion" } */
+
+/* PR77916: This failed with "error: invalid (pointer) operands to plus/minus"
+   after SLSR.  */
+
+typedef struct
+{
+  void *f1;
+} S;
+
+S *a;
+int b;
+
+void
+fn1 (void)
+{
+  for (; b; b++, a++)
+    a->f1 = b;
+}