The stmt comparison function for GIMPLE_ASSIGNs for tail merging
still looks like it deals with pre-tuples IL.  The following
attempts to fix this, not only comparing the first operand (sic!)
of stmts but all of them plus also compare the operation code.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

        PR tree-optimization/110556
        * tree-ssa-tail-merge.cc (gimple_equal_p): Check
        assign code and all operands of non-stores.

        * gcc.dg/torture/pr110556.c: New testcase.
---
 gcc/testsuite/gcc.dg/torture/pr110556.c | 42 +++++++++++++++++++++++++
 gcc/tree-ssa-tail-merge.cc              | 22 ++++++++++---
 2 files changed, 59 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr110556.c

diff --git a/gcc/testsuite/gcc.dg/torture/pr110556.c 
b/gcc/testsuite/gcc.dg/torture/pr110556.c
new file mode 100644
index 00000000000..bc60db885e2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr110556.c
@@ -0,0 +1,42 @@
+/* { dg-do run } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-additional-options "-fno-tree-fre -fno-delete-dead-exceptions 
-fnon-call-exceptions" } */
+
+typedef __INT32_TYPE__ int32_t;
+typedef __INT64_TYPE__ int64_t;
+
+static int64_t __attribute__((noinline,noclone))
+safe_mul_func_int64_t_s_s(int64_t si1, int64_t si2)
+{
+  return ((((si1 > 0) && (si2 > 0) && (si1 > ( (9223372036854775807L) / si2)))
+           || ((si1 > 0) && (si2 <= 0) && (si2 < ( (-9223372036854775807L -1) 
/ si1)))
+           || ((si1 <= 0) && (si2 > 0) && (si1 < ( (-9223372036854775807L -1) 
/ si2)))
+           || ((si1 <= 0) && (si2 <= 0) && (si1 != 0) && (si2 < ( 
(9223372036854775807L) / si1))))
+          ? ((si1)) : si1 * si2);
+}
+
+static int32_t g_93 = 0x947A4BBFL;
+static int32_t tt = 6;
+int64_t ty, ty1;
+
+static void func_34(void)
+{
+ ty=safe_mul_func_int64_t_s_s (g_93, -1L) ;
+}
+static void func_30(void)
+{
+  ty1=safe_mul_func_int64_t_s_s(0, tt);
+}
+static void func_6(void)
+{
+ for (int g_9 = 5; (g_9 >= 0); g_9 -= 1)
+ {
+  func_34();
+  func_30 ();
+ }
+}
+
+int main ()
+{
+ func_6();
+}
diff --git a/gcc/tree-ssa-tail-merge.cc b/gcc/tree-ssa-tail-merge.cc
index 13bc8532bf2..33acb649d5d 100644
--- a/gcc/tree-ssa-tail-merge.cc
+++ b/gcc/tree-ssa-tail-merge.cc
@@ -1165,6 +1165,9 @@ gimple_equal_p (same_succ *same_succ, gimple *s1, gimple 
*s2)
       return operand_equal_p (lhs1, lhs2, 0);
 
     case GIMPLE_ASSIGN:
+      if (gimple_assign_rhs_code (s1) != gimple_assign_rhs_code (s2))
+       return false;
+
       lhs1 = gimple_get_lhs (s1);
       lhs2 = gimple_get_lhs (s2);
       if (TREE_CODE (lhs1) != SSA_NAME
@@ -1172,11 +1175,20 @@ gimple_equal_p (same_succ *same_succ, gimple *s1, 
gimple *s2)
        return (operand_equal_p (lhs1, lhs2, 0)
                && gimple_operand_equal_value_p (gimple_assign_rhs1 (s1),
                                                 gimple_assign_rhs1 (s2)));
-      else if (TREE_CODE (lhs1) == SSA_NAME
-              && TREE_CODE (lhs2) == SSA_NAME)
-       return operand_equal_p (gimple_assign_rhs1 (s1),
-                               gimple_assign_rhs1 (s2), 0);
-      return false;
+
+      if (TREE_CODE (lhs1) != SSA_NAME
+         || TREE_CODE (lhs2) != SSA_NAME)
+       return false;
+
+      gcc_checking_assert (gimple_num_args (s1) == gimple_num_args (s2));
+      for (i = 0; i < gimple_num_args (s1); ++i)
+       {
+         t1 = gimple_arg (s1, i);
+         t2 = gimple_arg (s2, i);
+         if (!gimple_operand_equal_value_p (t1, t2))
+           return false;
+       }
+      return true;
 
     case GIMPLE_COND:
       t1 = gimple_cond_lhs (s1);
-- 
2.35.3

Reply via email to