]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gimple-fold: Don't replace `tmp = FP0 CMP FP1; if (tmp != 0)` over and over again...
authorAndrew Pinski <quic_apinski@quicinc.com>
Tue, 22 Apr 2025 16:40:28 +0000 (09:40 -0700)
committerAndrew Pinski <quic_apinski@quicinc.com>
Tue, 13 May 2025 15:51:31 +0000 (08:51 -0700)
with -ftrapping-math -fnon-call-exceptions and:
```
tmp = FP0 CMP FP1;

if (tmp != 0) ...
```
a call fold_stmt on the GIMPLE_COND will replace the above with
a new tmp each time and we even lose the eh informatin on the
previous comparison too.

Changes since v1:
* v2: Use INTEGRAL_TYPE_P instead of a check against BOOLEAN_TYPE.
      Add testcase which shows where losing of landing pad happened.

PR tree-optimization/119903
gcc/ChangeLog:

* gimple-fold.cc (replace_stmt_with_simplification): Reject for
noncall exceptions replacing comparison with itself.
gcc/testsuite/ChangeLog:

* g++.dg/tree-ssa/pr119903-1.C: New test.

Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
gcc/gimple-fold.cc
gcc/testsuite/g++.dg/tree-ssa/pr119903-1.C [new file with mode: 0644]

index e63fd6f2f2f28690f0cc1e9929402561a30eb91f..b8c1588365e275e684b5122fc283568536299839 100644 (file)
@@ -6276,6 +6276,32 @@ replace_stmt_with_simplification (gimple_stmt_iterator *gsi,
        }
       else if (!inplace)
        {
+         /* For throwing comparisons, see if the GIMPLE_COND is the same as
+            the comparison would be.
+            This can happen due to the match pattern for
+            `(ne (cmp @0 @1) integer_zerop)` which creates a new expression
+            for the comparison.  */
+         if (TREE_CODE_CLASS (code) == tcc_comparison
+             && flag_exceptions
+             && cfun->can_throw_non_call_exceptions
+             && operation_could_trap_p (code,
+                                        FLOAT_TYPE_P (TREE_TYPE (ops[0])),
+                                        false, NULL_TREE))
+           {
+             tree lhs = gimple_cond_lhs (cond_stmt);
+             if (gimple_cond_code (cond_stmt) == NE_EXPR
+                 && TREE_CODE (lhs) == SSA_NAME
+                 && INTEGRAL_TYPE_P (TREE_TYPE (lhs))
+                 && integer_zerop (gimple_cond_rhs (cond_stmt)))
+               {
+                 gimple *s = SSA_NAME_DEF_STMT (lhs);
+                 if (is_gimple_assign (s)
+                     && gimple_assign_rhs_code (s) == code
+                     && operand_equal_p (gimple_assign_rhs1 (s), ops[0])
+                     && operand_equal_p (gimple_assign_rhs2 (s), ops[1]))
+                   return false;
+               }
+           }
          tree res = maybe_push_res_to_seq (res_op, seq);
          if (!res)
            return false;
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr119903-1.C b/gcc/testsuite/g++.dg/tree-ssa/pr119903-1.C
new file mode 100644 (file)
index 0000000..605f989
--- /dev/null
@@ -0,0 +1,24 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "-O2 -fnon-call-exceptions -ftrapping-math -fdump-tree-optimized-eh" }
+
+// PR tree-optimization/119903
+// match and simplify would cause the internal throwable fp comparison
+// to become only external throwable and lose the landing pad.
+
+int f() noexcept;
+int g() noexcept;
+
+int m(double a)
+{
+  try {
+    if (a < 1.0)
+      return f();
+    return g();
+  }catch(...)
+  {
+        return -1;
+  }
+}
+
+// Make sure There is a landing pad for the non-call exception from the comparison.
+// { dg-final { scan-tree-dump "LP " "optimized" } }