]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
middle-end/103181 - fix operation_could_trap_p for vector division
authorRichard Biener <rguenther@suse.de>
Thu, 11 Nov 2021 08:40:36 +0000 (09:40 +0100)
committerRichard Biener <rguenther@suse.de>
Thu, 17 Feb 2022 09:31:20 +0000 (10:31 +0100)
For integer vector division we only checked for all zero vector
constants rather than checking whether any element in the constant
vector is zero.

It also fixes the adjustment to operation_could_trap_helper_p
where I failed to realize that RDIV_EXPR is also used for
fixed-point types.  It also fixes that handling by properly
checking for a fixed_zerop divisor.

2021-11-11  Richard Biener  <rguenther@suse.de>

PR middle-end/103181
PR middle-end/103248
* 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.
Properly handle fixed-point RDIV_EXPR.

* gcc.dg/torture/pr103181.c: New testcase.
* gcc.dg/pr103248.c: Likewise.

(cherry picked from commit 2f0c8f74daef93c0c7b33294213e7db6df58c4d1)

gcc/testsuite/gcc.dg/pr103248.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr103181.c [new file with mode: 0644]
gcc/tree-eh.c

diff --git a/gcc/testsuite/gcc.dg/pr103248.c b/gcc/testsuite/gcc.dg/pr103248.c
new file mode 100644 (file)
index 0000000..da6232d
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target fixed_point } */
+/* { dg-options "-fnon-call-exceptions" } */
+
+_Accum sa;
+int c;
+
+void div_csa() { c /= sa; }
diff --git a/gcc/testsuite/gcc.dg/torture/pr103181.c b/gcc/testsuite/gcc.dg/torture/pr103181.c
new file mode 100644 (file)
index 0000000..6bc705a
--- /dev/null
@@ -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;
+}
index 90e335ac74d2f8916379948c20e5f4bee3c7ae6d..3917d00cc9cad3203677adae4a03e00d7bbd9b8d 100644 (file)
@@ -2462,13 +2462,35 @@ 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 (fp_operation)
+       {
+         if (honor_snans)
+           return true;
+         return flag_trapping_math;
+       }
+      /* Fixed point operations also use RDIV_EXPR.  */
+      if (!TREE_CONSTANT (divisor) || fixed_zerop (divisor))
+       return true;
       return false;
 
     case LT_EXPR: