We may not simply rewrite def stmts of associative operands as
they might have multiple uses. The following appropriately
creates a new stmt instead.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.
PR tree-optimization/125786
* tree-ssa-reassoc.cc (optimize_vec_cond_expr): Create a new
stmt instead of rewriting an existing possibly multi-use one.
* gcc.dg/torture/pr125786.c: New testcase.
---
gcc/testsuite/gcc.dg/torture/pr125786.c | 30 +++++++++++++++++++++++++
gcc/tree-ssa-reassoc.cc | 14 +++++++-----
2 files changed, 38 insertions(+), 6 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/torture/pr125786.c
diff --git a/gcc/testsuite/gcc.dg/torture/pr125786.c
b/gcc/testsuite/gcc.dg/torture/pr125786.c
new file mode 100644
index 00000000000..4b432f9d2f0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr125786.c
@@ -0,0 +1,30 @@
+/* { dg-do run } */
+
+#define length 16
+typedef int type;
+typedef type v8i64 __attribute__((vector_size(sizeof(type)*length)));
+v8i64 g6, g27;
+_Bool main_c14;
+
+__attribute__((noipa))
+static
+void f(v8i64 *a)
+{
+ for(int i =0;i<length;i++)
+ if ((*a)[i] != -1)
+ __builtin_abort();
+}
+
+int main()
+{
+ if (main_c14) goto lbl_br43;
+lbl_bf7:
+ g6 = 0 <= g27;
+ g27 = g27 <= g27;
+ g27 = g6 > g27;
+lbl_br43:
+ g6 = g6 | g27;
+ if (main_c14) goto lbl_bf7;
+ g6 = g6 * g27 == 0;
+ f(&g6);
+}
diff --git a/gcc/tree-ssa-reassoc.cc b/gcc/tree-ssa-reassoc.cc
index 4b47fb20f3a..924742878ea 100644
--- a/gcc/tree-ssa-reassoc.cc
+++ b/gcc/tree-ssa-reassoc.cc
@@ -4234,7 +4234,7 @@ optimize_vec_cond_expr (tree_code opcode,
vec<operand_entry *> *ops)
for (i = 0; i < length; ++i)
{
- tree elt0 = (*ops)[i]->op;
+ tree &elt0 = (*ops)[i]->op;
gassign *stmt0, *vcond0;
bool invert;
@@ -4282,11 +4282,13 @@ optimize_vec_cond_expr (tree_code opcode,
vec<operand_entry *> *ops)
gimple_stmt_iterator gsi = gsi_for_stmt (vcond0);
tree exp = force_gimple_operand_gsi (&gsi, comb, true, NULL_TREE,
true, GSI_SAME_STMT);
- if (invert)
- swap_ssa_operands (vcond0, gimple_assign_rhs2_ptr (vcond0),
- gimple_assign_rhs3_ptr (vcond0));
- gimple_assign_set_rhs1 (vcond0, exp);
- update_stmt (vcond0);
+ tree res = gimple_build (&gsi, true, GSI_SAME_STMT, UNKNOWN_LOCATION,
+ VEC_COND_EXPR, TREE_TYPE (elt0), exp,
+ constant_boolean_node (true,
+ TREE_TYPE (elt0)),
+ constant_boolean_node (false,
+ TREE_TYPE (elt0)));
+ elt0 = res;
elt1 = error_mark_node;
any_changes = true;
--
2.51.0