Floating-point to integer conversions can be inexact or invalid (e.g., due to
overflow or NaN).  However, since users of operation_could_trap_p infer the
bool FP_OPERATION argument from the expression's type, FIX_TRUNC_EXPR is
considered non-trapping here.

This patch handles FIX_TRUNC_EXPR explicitly.

gcc/ChangeLog:

        * tree-eh.cc (operation_could_trap_helper_p):  Cover FIX_TRUNC_EXPR
        explicitly.

gcc/testsuite/ChangeLog:

        * gcc.dg/tree-ssa/ifcvt-fix-trunc-1.c: New test.
        * gcc.dg/tree-ssa/ifcvt-fix-trunc-2.c: New test.
---
 .../gcc.dg/tree-ssa/ifcvt-fix-trunc-1.c        | 18 ++++++++++++++++++
 .../gcc.dg/tree-ssa/ifcvt-fix-trunc-2.c        |  6 ++++++
 gcc/tree-eh.cc                                 |  5 +++++
 3 files changed, 29 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ifcvt-fix-trunc-1.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ifcvt-fix-trunc-2.c

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ifcvt-fix-trunc-1.c 
b/gcc/testsuite/gcc.dg/tree-ssa/ifcvt-fix-trunc-1.c
new file mode 100644
index 00000000000..c65441ad679
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ifcvt-fix-trunc-1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-ifcvt-stats" } */
+
+void test (int *dst, float *arr, int *pred, int n)
+{
+  for (int i = 0; i < n; i++)
+    {
+      int pred_i = pred[i];
+      float arr_i = arr[i];
+
+      dst[i] = pred_i ? (int)arr_i : 5;
+    }
+}
+
+/* We expect this to fail if_convertible_loop_p so long as we have no
+   conditional IFN for FIX_TRUNC_EXPR.  */
+
+/* { dg-final { scan-tree-dump-times "Applying if-conversion" 0 "ifcvt" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ifcvt-fix-trunc-2.c 
b/gcc/testsuite/gcc.dg/tree-ssa/ifcvt-fix-trunc-2.c
new file mode 100644
index 00000000000..628b754e94d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ifcvt-fix-trunc-2.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fno-trapping-math 
-fdump-tree-ifcvt-stats" } */
+
+#include "ifcvt-fix-trunc-1.c"
+
+/* { dg-final { scan-tree-dump-times "Applying if-conversion" 1 "ifcvt" } } */
diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc
index a4d59954c05..154e8fafb12 100644
--- a/gcc/tree-eh.cc
+++ b/gcc/tree-eh.cc
@@ -2538,6 +2538,11 @@ operation_could_trap_helper_p (enum tree_code op,
       /* Constructing an object cannot trap.  */
       return false;
 
+    case FIX_TRUNC_EXPR:
+      /* Don't rely on FP_OPERATION to cover FP->INT conversions,
+        since the complete expression does not have a FP type.  */
+      return flag_trapping_math;
+
     case COND_EXPR:
     case VEC_COND_EXPR:
       /* Whether *COND_EXPR can trap depends on whether the
-- 
2.34.1

Reply via email to