https://gcc.gnu.org/g:66fc62e9c7b55f287cc523854ca330b6531760b6

commit r16-1171-g66fc62e9c7b55f287cc523854ca330b6531760b6
Author: Spencer Abson <spencer.ab...@arm.com>
Date:   Tue Jun 3 12:15:12 2025 +0000

    middle-end: Fix operation_could_trap_p for FIX_TRUNC expressions
    
    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, the FIX_TRUNC family
    are considered non-trapping here.
    
    This patch handles them explicitly.
    
    gcc/ChangeLog:
    
            * tree-eh.cc (operation_could_trap_helper_p): Cover FIX_TRUNC
            expressions explicitly.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/aarch64/sve/pr96357.c: Change to avoid producing
            a conditional FIX_TRUNC_EXPR, whilst still reproducing the bug
            in PR96357.
            * gcc.dg/tree-ssa/ifcvt-fix-trunc-1.c: New test.
            * gcc.dg/tree-ssa/ifcvt-fix-trunc-2.c: Likewise.

Diff:
---
 gcc/testsuite/gcc.dg/tree-ssa/ifcvt-fix-trunc-1.c | 19 +++++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/ifcvt-fix-trunc-2.c |  6 ++++++
 gcc/testsuite/gcc.target/aarch64/sve/pr96357.c    |  8 ++++----
 gcc/tree-eh.cc                                    |  7 +++++++
 4 files changed, 36 insertions(+), 4 deletions(-)

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 000000000000..801a53fa30bd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ifcvt-fix-trunc-1.c
@@ -0,0 +1,19 @@
+  /* { 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 000000000000..628b754e94d9
--- /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/testsuite/gcc.target/aarch64/sve/pr96357.c 
b/gcc/testsuite/gcc.target/aarch64/sve/pr96357.c
index 9a7f912e529f..6dd0409f3c88 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/pr96357.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/pr96357.c
@@ -5,10 +5,10 @@ int d;
 
 void
 f1(char f, char *g, char *h, char *l, char *n) {
-  double i = d, j = 1.0 - f, k = j ? d : j;
-  if (k == 1.0)
-    i = 0.0;
-  *l = *n = *g = *h = i * 0.5;
+  double j = 1.0 - f, k = j ? d : j;
+
+  char i = (k == 1.0) ? 10 : 50;
+  *l = *n = *g = *h = i;
 }
 
 void
diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc
index a4d59954c059..8cc81ebcf5e9 100644
--- a/gcc/tree-eh.cc
+++ b/gcc/tree-eh.cc
@@ -2538,6 +2538,13 @@ operation_could_trap_helper_p (enum tree_code op,
       /* Constructing an object cannot trap.  */
       return false;
 
+    case FIX_TRUNC_EXPR:
+    case VEC_PACK_FIX_TRUNC_EXPR:
+    case VEC_UNPACK_FIX_TRUNC_HI_EXPR:
+    case VEC_UNPACK_FIX_TRUNC_LO_EXPR:
+      /* The FIX_TRUNC family are always potentially trapping.  */
+      return flag_trapping_math;
+
     case COND_EXPR:
     case VEC_COND_EXPR:
       /* Whether *COND_EXPR can trap depends on whether the

Reply via email to