From a67dab0de8633e27d3a9989cd6b5edcadf8c9084 Mon Sep 17 00:00:00 2001 From: Bill Schmidt Date: Mon, 24 Oct 2016 02:41:12 +0000 Subject: [PATCH] backport: re PR tree-optimization/77916 (ICE in verify_gimple_in_cfg: invalid (pointer) operands to plus/minus) [gcc] 2016-10-23 Bill Schmidt Backport from mainline 2016-10-17 Bill Schmidt 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. (insert_initializers): Requirement of initializer for -1 should be based on pointer-typedness of the candidate basis. [gcc/testsuite] 2016-10-23 Bill Schmidt Backport from mainline 2016-10-17 Bill Schmidt PR tree-optimization/77916 * gcc.dg/torture/pr77916.c: New. From-SVN: r241462 --- gcc/ChangeLog | 16 ++++++++++++++ gcc/gimple-ssa-strength-reduction.c | 29 +++++++++++++------------- gcc/testsuite/ChangeLog | 8 +++++++ gcc/testsuite/gcc.dg/torture/pr77916.c | 20 ++++++++++++++++++ 4 files changed, 59 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr77916.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 880196d4bd19..3260d52317fe 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2016-10-23 Bill Schmidt + + Backport from mainline + 2016-10-17 Bill Schmidt + + 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. + (insert_initializers): Requirement of initializer for -1 should be + based on pointer-typedness of the candidate basis. + 2016-10-19 Uros Bizjak PR target/77991 diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c index cc56a6e86e7d..b9598a127d6d 100644 --- a/gcc/gimple-ssa-strength-reduction.c +++ b/gcc/gimple-ssa-strength-reduction.c @@ -2191,35 +2191,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); @@ -2538,13 +2544,13 @@ 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; + Exception: increments of 0, 1 never need initializers; and phi adjustments don't ever provide initializers. */ if (c->kind == CAND_ADD && !is_phi_adjust && c->index == increment && (wi::gts_p (increment, 1) - || wi::lts_p (increment, -1)) + || wi::lts_p (increment, 0)) && (gimple_assign_rhs_code (c->cand_stmt) == PLUS_EXPR || gimple_assign_rhs_code (c->cand_stmt) == POINTER_PLUS_EXPR)) { @@ -2857,11 +2863,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 @@ -3148,7 +3149,7 @@ insert_initializers (slsr_cand_t c) if (!profitable_increment_p (i) || incr == 1 || (incr == -1 - && gimple_assign_rhs_code (c->cand_stmt) != POINTER_PLUS_EXPR) + && (!POINTER_TYPE_P (lookup_cand (c->basis)->cand_type))) || incr == 0) continue; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 020ee03d14d2..b97119d3adfd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2016-10-23 Bill Schmidt + + Backport from mainline + 2016-10-17 Bill Schmidt + + PR tree-optimization/77916 + * gcc.dg/torture/pr77916.c: New. + 2016-10-19 Uros Bizjak PR target/77991 diff --git a/gcc/testsuite/gcc.dg/torture/pr77916.c b/gcc/testsuite/gcc.dg/torture/pr77916.c new file mode 100644 index 000000000000..f29f099d5862 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr77916.c @@ -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; +} -- 2.47.2