When undistribute_ops_list calls linearize_expr with an outer
RDIV_EXPR we fail to consider that RDIV_EXPR is not associative
and end up linearizing the RHS.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.
PR tree-optimization/128089
* tree-ssa-reassoc.cc (linearize_expr_tree): Do not make
binrhsisreassoc true unless is_associative.
* gcc.dg/pr128089.c: New testcase.
---
gcc/testsuite/gcc.dg/pr128089.c | 17 +++++++++++++++++
gcc/tree-ssa-reassoc.cc | 10 ++++++----
2 files changed, 23 insertions(+), 4 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/pr128089.c
diff --git a/gcc/testsuite/gcc.dg/pr128089.c b/gcc/testsuite/gcc.dg/pr128089.c
new file mode 100644
index 00000000000..718513836b0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr128089.c
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fassociative-math -fno-trapping-math -fno-signed-zeros"
} */
+
+__attribute__ ((noipa)) double
+f (double a)
+{
+ return (a / 3) / (a / 6) + a * a;
+}
+
+int
+main (void)
+{
+ double result = f (6);
+ if (result != 38)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/tree-ssa-reassoc.cc b/gcc/tree-ssa-reassoc.cc
index 8df554ebc8c..10c9c721a4e 100644
--- a/gcc/tree-ssa-reassoc.cc
+++ b/gcc/tree-ssa-reassoc.cc
@@ -6229,7 +6229,8 @@ linearize_expr_tree (vec<operand_entry *> *ops, gimple
*stmt,
if (TREE_CODE (binrhs) == SSA_NAME)
{
binrhsdef = SSA_NAME_DEF_STMT (binrhs);
- binrhsisreassoc = (is_reassociable_op (binrhsdef, rhscode, loop)
+ binrhsisreassoc = (is_associative
+ && is_reassociable_op (binrhsdef, rhscode, loop)
&& !stmt_could_throw_p (cfun, binrhsdef));
}
@@ -6296,9 +6297,10 @@ linearize_expr_tree (vec<operand_entry *> *ops, gimple
*stmt,
binrhs = gimple_assign_rhs2 (stmt);
}
- gcc_assert (TREE_CODE (binrhs) != SSA_NAME
- || !is_reassociable_op (SSA_NAME_DEF_STMT (binrhs),
- rhscode, loop));
+ gcc_checking_assert (TREE_CODE (binrhs) != SSA_NAME
+ || !is_associative
+ || !is_reassociable_op (SSA_NAME_DEF_STMT (binrhs),
+ rhscode, loop));
linearize_expr_tree (ops, SSA_NAME_DEF_STMT (binlhs),
is_associative, set_visited);
base-commit: ab8d26c0d68f49841a8225be53a7f947fb664476
--
2.51.0