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. --- .../gcc.dg/tree-ssa/ifcvt-fix-trunc-1.c | 19 +++++++++++++++++++ .../gcc.dg/tree-ssa/ifcvt-fix-trunc-2.c | 6 ++++++ .../gcc.target/aarch64/sve/pr96357.c | 8 ++++---- gcc/tree-eh.cc | 7 +++++++ 4 files changed, 36 insertions(+), 4 deletions(-) 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..801a53fa30b --- /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 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/testsuite/gcc.target/aarch64/sve/pr96357.c b/gcc/testsuite/gcc.target/aarch64/sve/pr96357.c index 9a7f912e529..6dd0409f3c8 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 a4d59954c05..8cc81ebcf5e 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 -- 2.34.1