From a929f2662ef33c06ad5b41f2a3df0c0833bbc405 Mon Sep 17 00:00:00 2001 From: Bill Schmidt Date: Mon, 17 Oct 2016 22:08:56 +0000 Subject: [PATCH] re PR tree-optimization/77916 (ICE in verify_gimple_in_cfg: invalid (pointer) operands to plus/minus) [gcc] 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. [gcc/testsuite] 2016-10-17 Bill Schmidt PR tree-optimization/77916 * gcc.dg/torture/pr77916.c: New. From-SVN: r241281 --- gcc/ChangeLog | 11 +++++++++ gcc/gimple-ssa-strength-reduction.c | 31 ++++++++++++++------------ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/torture/pr77916.c | 20 +++++++++++++++++ 4 files changed, 53 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr77916.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b512e4b9bbc..89a03e90c51 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +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. + 2016-10-17 Yuri Rumyantsev * dominance.c (dom_info::dom_info): Add new constructor for region diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c index 72862f85144..2ef5c482582 100644 --- a/gcc/gimple-ssa-strength-reduction.c +++ b/gcc/gimple-ssa-strength-reduction.c @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7d4a4416e49..ddad6fc9a89 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-10-17 Bill Schmidt + + PR tree-optimization/77916 + * gcc.dg/torture/pr77916.c: New. + 2016-10-17 Steven G. Kargl 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 index 00000000000..f29f099d586 --- /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.30.2