aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Pinski <quic_apinski@quicinc.com>2025-07-05 08:40:45 -0700
committerAndrew Pinski <quic_apinski@quicinc.com>2025-07-06 07:58:48 -0700
commite17e3de4bbb1848ce1ce7d69d7786b92f1969b11 (patch)
treeeb7902fceef67f7df31b6845ffb5e4aeb6535dfb
parent5c2dc85c1923af118a9ec9657dc969fd3d95498a (diff)
downloadgcc-e17e3de4bbb1848ce1ce7d69d7786b92f1969b11.zip
gcc-e17e3de4bbb1848ce1ce7d69d7786b92f1969b11.tar.gz
gcc-e17e3de4bbb1848ce1ce7d69d7786b92f1969b11.tar.bz2
cdce: Fix non-call exceptions with signaling nans [PR120951]
The cdce code introduces a test for a NaN using the EQ_EXPR code. The problem is EQ_EXPR can cause an exception with non-call exceptions and signaling nans turned on. This is now correctly rejected by the verfier since r16-241-g4c40e3d7b9152f. The fix is seperate out the comparison into its own statement from the GIMPLE_COND. Bootstrapped and tested on x86_64-linux-gnu with no regressions. PR tree-optimization/120951 gcc/ChangeLog: * tree-call-cdce.cc (use_internal_fn): For non-call exceptions with EQ_EXPR can throw for floating point types, then create the EQ_EXPR seperately. gcc/testsuite/ChangeLog: * gcc.dg/torture/pr120951-1.c: New test. Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr120951-1.c12
-rw-r--r--gcc/tree-call-cdce.cc17
2 files changed, 27 insertions, 2 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr120951-1.c b/gcc/testsuite/gcc.dg/torture/pr120951-1.c
new file mode 100644
index 0000000..4e2b41d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr120951-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-fnon-call-exceptions -fsignaling-nans" } */
+
+/* PR tree-optimization/120951 */
+
+/* cdce would create a trapping comparison inside a condition.
+ tests to make sure that does not happen. */
+
+double f(double r, double i) {
+ return __builtin_fmod(r, i);
+}
+
diff --git a/gcc/tree-call-cdce.cc b/gcc/tree-call-cdce.cc
index 649c1e2..3edea75 100644
--- a/gcc/tree-call-cdce.cc
+++ b/gcc/tree-call-cdce.cc
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see
#include "builtins.h"
#include "internal-fn.h"
#include "tree-dfa.h"
+#include "tree-eh.h"
/* This pass serves two closely-related purposes:
@@ -1222,8 +1223,20 @@ use_internal_fn (gcall *call)
{
/* Skip the call if LHS == LHS. If we reach here, EDOM is the only
valid errno value and it is used iff the result is NaN. */
- conds.quick_push (gimple_build_cond (EQ_EXPR, lhs, lhs,
- NULL_TREE, NULL_TREE));
+ /* In the case of non call exceptions, with signaling NaNs, EQ_EXPR
+ can throw an exception and that can't be part of the GIMPLE_COND. */
+ if (flag_exceptions
+ && cfun->can_throw_non_call_exceptions
+ && operation_could_trap_p (EQ_EXPR, true, false, NULL_TREE))
+ {
+ tree b = make_ssa_name (boolean_type_node);
+ conds.quick_push (gimple_build_assign (b, EQ_EXPR, lhs, lhs));
+ conds.quick_push (gimple_build_cond (NE_EXPR, b, boolean_false_node,
+ NULL_TREE, NULL_TREE));
+ }
+ else
+ conds.quick_push (gimple_build_cond (EQ_EXPR, lhs, lhs,
+ NULL_TREE, NULL_TREE));
nconds++;
/* Try replacing the original call with a direct assignment to