https://gcc.gnu.org/g:354649551eef48f58ceb00633d56daee23139413

commit r17-5512-g354649551eef48f58ceb00633d56daee23139413
Author: Richard Biener <[email protected]>
Date:   Fri Oct 23 15:14:11 2026 +0200

    tree-optimization/128089 - fix bad linearization in reassoc
    
    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.
    
            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.

Diff:
---
 gcc/testsuite/gcc.dg/pr128089.c | 17 +++++++++++++++++
 gcc/tree-ssa-reassoc.cc         | 10 ++++++----
 2 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/pr128089.c b/gcc/testsuite/gcc.dg/pr128089.c
new file mode 100644
index 000000000000..718513836b09
--- /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 8df554ebc8ce..10c9c721a4e6 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);

Reply via email to