Commit a929f266 by Bill Schmidt Committed by William Schmidt

re PR tree-optimization/77916 (ICE in verify_gimple_in_cfg: invalid (pointer)…

re PR tree-optimization/77916 (ICE in verify_gimple_in_cfg: invalid (pointer) operands to plus/minus)

[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
parent 4acf2055
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> 2016-10-17 Yuri Rumyantsev <ysrumyan@gmail.com>
* dominance.c (dom_info::dom_info): Add new constructor for region * dominance.c (dom_info::dom_info): Add new constructor for region
......
...@@ -2154,35 +2154,41 @@ create_add_on_incoming_edge (slsr_cand_t c, tree basis_name, ...@@ -2154,35 +2154,41 @@ create_add_on_incoming_edge (slsr_cand_t c, tree basis_name,
basis_type = TREE_TYPE (basis_name); basis_type = TREE_TYPE (basis_name);
lhs = make_temp_ssa_name (basis_type, NULL, "slsr"); 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) if (known_stride)
{ {
tree bump_tree; tree bump_tree;
enum tree_code code = PLUS_EXPR; enum tree_code code = plus_code;
widest_int bump = increment * wi::to_widest (c->stride); 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; code = MINUS_EXPR;
bump = -bump; 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); new_stmt = gimple_build_assign (lhs, code, basis_name, bump_tree);
} }
else else
{ {
int i; 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); i = incr_vec_index (negate_incr ? -increment : increment);
gcc_assert (i >= 0); gcc_assert (i >= 0);
if (incr_vec[i].initializer) 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, new_stmt = gimple_build_assign (lhs, code, basis_name,
incr_vec[i].initializer); incr_vec[i].initializer);
} }
else if (increment == 1) 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) else if (increment == -1)
new_stmt = gimple_build_assign (lhs, MINUS_EXPR, basis_name, new_stmt = gimple_build_assign (lhs, MINUS_EXPR, basis_name,
c->stride); c->stride);
...@@ -2500,12 +2506,14 @@ record_increment (slsr_cand_t c, widest_int increment, bool is_phi_adjust) ...@@ -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 /* Optimistically record the first occurrence of this increment
as providing an initializer (if it does); we will revise this as providing an initializer (if it does); we will revise this
opinion later if it doesn't dominate all other occurrences. 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. */ 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 if (c->kind == CAND_ADD
&& !is_phi_adjust && !is_phi_adjust
&& c->index == increment && 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) == PLUS_EXPR
|| gimple_assign_rhs_code (c->cand_stmt) == POINTER_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) ...@@ -2819,11 +2827,6 @@ analyze_increments (slsr_cand_t first_dep, machine_mode mode, bool speed)
&& !POINTER_TYPE_P (first_dep->cand_type))) && !POINTER_TYPE_P (first_dep->cand_type)))
incr_vec[i].cost = COST_NEUTRAL; 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 /* 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. the candidate's type to its stride's type can lose precision.
This could eventually be handled better by expressly retaining the This could eventually be handled better by expressly retaining the
......
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> 2016-10-17 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/77978 PR fortran/77978
......
/* { 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment