aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>2016-10-17 22:08:56 +0000
committerWilliam Schmidt <wschmidt@gcc.gnu.org>2016-10-17 22:08:56 +0000
commita929f2662ef33c06ad5b41f2a3df0c0833bbc405 (patch)
tree34319a35592833a44e76589fd700c44a0534b9e3 /gcc
parent4acf205523e33923a55d542aca44c2670e970a3a (diff)
downloadgcc-a929f2662ef33c06ad5b41f2a3df0c0833bbc405.zip
gcc-a929f2662ef33c06ad5b41f2a3df0c0833bbc405.tar.gz
gcc-a929f2662ef33c06ad5b41f2a3df0c0833bbc405.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/gimple-ssa-strength-reduction.c31
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr77916.c20
4 files changed, 53 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b512e4b..89a03e9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c
index 72862f8..2ef5c48 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 7d4a441..ddad6fc 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..f29f099
--- /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;
+}