From: Richard Biener Date: Thu, 11 Nov 2021 08:40:36 +0000 (+0100) Subject: middle-end/103181 - fix operation_could_trap_p for vector division X-Git-Tag: basepoints/gcc-13~3164 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a5fed4063f428a14f5b91533d5954b9bf4e3e7db;p=thirdparty%2Fgcc.git middle-end/103181 - fix operation_could_trap_p for vector division For integer vector division we only checked for all zero vector constants rather than checking whether any element in the constant vector is zero. 2021-11-11 Richard Biener PR middle-end/103181 * tree-eh.c (operation_could_trap_helper_p): Properly check vector constants for a zero element for integer division. Separate floating point and integer division code. * gcc.dg/torture/pr103181.c: New testcase. --- diff --git a/gcc/testsuite/gcc.dg/torture/pr103181.c b/gcc/testsuite/gcc.dg/torture/pr103181.c new file mode 100644 index 000000000000..6bc705ab52eb --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr103181.c @@ -0,0 +1,24 @@ +/* { dg-do run } */ + +typedef unsigned char __attribute__((__vector_size__ (2))) U; +typedef unsigned short S; +typedef unsigned int __attribute__((__vector_size__ (64))) V; + +V v; +U a, b, c; + +U +foo (S s) +{ + v += __builtin_bswap16 (s) || (S) (a / ((U){3, 0})); + return b + c; +} + +int +main (void) +{ + U x = foo (4); + if (x[0] || x[1]) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 3a09de95025b..3eff07fc8feb 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -2454,15 +2454,31 @@ operation_could_trap_helper_p (enum tree_code op, case FLOOR_MOD_EXPR: case ROUND_MOD_EXPR: case TRUNC_MOD_EXPR: - case RDIV_EXPR: - if (honor_snans) - return true; - if (fp_operation) - return flag_trapping_math; if (!TREE_CONSTANT (divisor) || integer_zerop (divisor)) return true; + if (TREE_CODE (divisor) == VECTOR_CST) + { + /* Inspired by initializer_each_zero_or_onep. */ + unsigned HOST_WIDE_INT nelts = vector_cst_encoded_nelts (divisor); + if (VECTOR_CST_STEPPED_P (divisor) + && !TYPE_VECTOR_SUBPARTS (TREE_TYPE (divisor)) + .is_constant (&nelts)) + return true; + for (unsigned int i = 0; i < nelts; ++i) + { + tree elt = vector_cst_elt (divisor, i); + if (integer_zerop (elt)) + return true; + } + } return false; + case RDIV_EXPR: + if (honor_snans) + return true; + gcc_assert (fp_operation); + return flag_trapping_math; + case LT_EXPR: case LE_EXPR: case GT_EXPR: