The following adds gimple_could_raise_ieee_exception_p and honors it
in DCE and DSE.

This shows, for example in gcc.dg/tree-ssa/fp-trapping-cmp-4.c,
that some passes fail to clean up after themselves when they
no longer can rely on DCE.

Bootstrapped and tested on x86_64-unknown-linux-gnu.  I think we
shouldn't do something like this without also swapping the
default of -ftrapping-math.  Full testsuite fallout is

+FAIL: g++.dg/opt/pr94589-5.C  -std=gnu++20  scan-tree-dump-times 
optimized "[ij
]_[0-9]+\\\\(D\\\\) (?:<|<=|>|>=) [ij]_[0-9]+\\\\(D\\\\)" 8
+FAIL: gcc.dg/pr94589-5.c scan-tree-dump-times optimized 
"[ij]_[0-9]+\\\\(D\\\\) (?:<|<=|>|>=) [ij]_[0-9]+\\\\(D\\\\)" 24
+FAIL: gcc.dg/pr94589-5.c scan-tree-dump-times optimized 
"i_[0-9]+\\\\(D\\\\) (?:<|<=|>|>=) 5\\\\.0" 24
+FAIL: gcc.dg/tree-ssa/fp-trapping-cmp-4.c scan-tree-dump-times optimized 
" < " 1
+FAIL: gcc.dg/tree-ssa/fp-trapping-cmp-5.c scan-tree-dump-times optimized 
" < " 1
+FAIL: gcc.dg/tree-ssa/fp-trapping-cmp-8.c scan-tree-dump dce3 
"a_[0-9]+\\\\(D\\\\) > b_[0-9]+\\\\(D\\\\)"
+FAIL: gcc.dg/tree-ssa/pr125385.c scan-tree-dump-not optimized 
"\\\\(float\\\\)"
+FAIL: gcc.dg/tree-ssa/sincos-ice-on-ifn_sin-call.c (internal compiler 
error: in expand_fn_using_insn, at internal-fn.cc:270)
+FAIL: gcc.dg/tree-ssa/sincos-ice-on-ifn_sin-call.c (test for excess 
errors)
+FAIL: gcc.dg/tree-ssa/tailcall-9.c scan-tree-dump tailc "Found tail call"
+FAIL: gcc.dg/vect/bb-slp-48.c -flto -ffat-lto-objects  
scan-tree-dump-times optimized " \\\\+ " 4
+FAIL: gcc.dg/vect/bb-slp-48.c scan-tree-dump-times optimized " \\\\+ " 4
+FAIL: gcc.target/i386/opt-1.c scan-assembler prefetcht0
+FAIL: gcc.target/i386/opt-2.c scan-assembler prefetcht0
+FAIL: gcc.target/i386/pr92645-3.c scan-tree-dump-times cddce1 
"BIT_FIELD_REF" 4

I'll note that, of course, RTL DCE will still elide the instructions
(so does simple-DCE on GIMPLE).  Preserving the stmts won't help
with reliable access through the FP environment (one more option for
a -fno-trapping-math default).  Maybe we can really go forward with
-fno-trapping-math by default for GCC 17?

Richard.

        PR tree-optimization/53805
        * gimple.h (gimple_could_raise_ieee_exception_p): Declare.
        * gimple.cc (gimple_could_raise_ieee_exception_p): New function.
        * tree-ssa-dce.cc (mark_stmt_if_obviously_necessary):
        Statements that might raise IEEE exceptions are necessary.
        * tree-ssa-dse.cc (pass_dse::execute): Likewise.

        * gcc.dg/tree-ssa/fp-trapping-cmp-9.c: New testcase.
---
 gcc/gimple.cc                                 | 32 +++++++++++++++++++
 gcc/gimple.h                                  |  1 +
 .../gcc.dg/tree-ssa/fp-trapping-cmp-9.c       |  9 ++++++
 gcc/tree-ssa-dce.cc                           |  7 ++++
 gcc/tree-ssa-dse.cc                           |  3 +-
 5 files changed, 51 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/fp-trapping-cmp-9.c

diff --git a/gcc/gimple.cc b/gcc/gimple.cc
index 04ad17f5955..72a7e3f9603 100644
--- a/gcc/gimple.cc
+++ b/gcc/gimple.cc
@@ -2493,6 +2493,38 @@ gimple_assign_rhs_could_trap_p (gimple *s)
   return gimple_could_trap_p_1 (s, true, false);
 }
 
+/* Return true if STMT could raise a IEEE exception.  */
+
+bool
+gimple_could_raise_ieee_exception_p (const gimple *stmt)
+{
+  if (!flag_trapping_math)
+    return false;
+
+  switch (gimple_code (stmt))
+    {
+    case GIMPLE_ASSIGN:
+      {
+       enum tree_code code = gimple_assign_rhs_code (stmt);
+       return (!gimple_assign_single_p (stmt)
+               && code != COND_EXPR
+               && FLOAT_TYPE_P
+                    (TREE_TYPE (TREE_CODE_CLASS (code) == tcc_comparison
+                                ? gimple_assign_rhs1 (stmt)
+                                : gimple_assign_lhs (stmt)))
+               && operation_could_trap_p (code, true, false, NULL_TREE));
+      }
+    case GIMPLE_COND:
+      return (FLOAT_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)))
+             && operation_could_trap_p (gimple_cond_code (stmt), true, false,
+                                        NULL_TREE));
+    default:
+      /* ???  This is incomplete, gcall and gasm can as well.  */
+      ;
+    }
+
+  return false;
+}
 
 /* Print debugging information for gimple stmts generated.  */
 
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 82045c44bbe..37a86061c48 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -1652,6 +1652,7 @@ void gimple_move_vops (gimple *, gimple *);
 bool gimple_has_side_effects (const gimple *);
 bool gimple_could_trap_p_1 (const gimple *, bool, bool);
 bool gimple_could_trap_p (const gimple *);
+bool gimple_could_raise_ieee_exception_p (const gimple *);
 bool gimple_assign_rhs_could_trap_p (gimple *);
 extern void dump_gimple_statistics (void);
 unsigned get_gimple_rhs_num_ops (enum tree_code);
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/fp-trapping-cmp-9.c 
b/gcc/testsuite/gcc.dg/tree-ssa/fp-trapping-cmp-9.c
new file mode 100644
index 00000000000..b27386408ca
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/fp-trapping-cmp-9.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-optimized" } */
+
+void f(double a,double b)
+{
+  _Bool c = a>b;
+}
+
+/* { dg-final { scan-tree-dump "a_\[0-9\]\+\\\(D\\\) > b_\[0-9\]\+\\\(D\\\)" 
"optimized" } } */
diff --git a/gcc/tree-ssa-dce.cc b/gcc/tree-ssa-dce.cc
index a5391290c4d..c511177c16d 100644
--- a/gcc/tree-ssa-dce.cc
+++ b/gcc/tree-ssa-dce.cc
@@ -503,6 +503,13 @@ mark_stmt_if_obviously_necessary (gimple *stmt, bool 
aggressive)
       return;
     }
 
+  /* Preserve statements possibly setting IEEE exceptions.  */
+  if (gimple_could_raise_ieee_exception_p (stmt))
+    {
+      mark_stmt_necessary (stmt, true);
+      return;
+    }
+
   if ((gimple_vdef (stmt) && keep_all_vdefs_p ())
       || stmt_may_clobber_global_p (stmt, false))
     {
diff --git a/gcc/tree-ssa-dse.cc b/gcc/tree-ssa-dse.cc
index 0623f2c9090..62ccd87c036 100644
--- a/gcc/tree-ssa-dse.cc
+++ b/gcc/tree-ssa-dse.cc
@@ -1732,7 +1732,8 @@ pass_dse::execute (function *fun)
                  && !gimple_has_side_effects (stmt)
                  && !is_ctrl_altering_stmt (stmt)
                  && (!stmt_could_throw_p (fun, stmt)
-                     || fun->can_delete_dead_exceptions))
+                     || fun->can_delete_dead_exceptions)
+                 && !gimple_could_raise_ieee_exception_p (stmt))
                {
                  if (dump_file && (dump_flags & TDF_DETAILS))
                    {
-- 
2.51.0

Reply via email to