Hi!

If any of the operands of the UBSAN_{ADD,SUB,MUL}_OVERFLOW ifn with
vector operand is a uniform vector, expanding it as VCE on the VECTOR_CST
followed by ARRAY_REF with variable index in the loop is unnecessarily
expensive and nothing fixes it afterwards.
This works around ICE on s390 at least for the uniform vectors.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2017-03-07  Jakub Jelinek  <ja...@redhat.com>

        PR sanitizer/79904
        * internal-fn.c (expand_vector_ubsan_overflow): If arg0 or arg1
        is a uniform vector, use uniform_vector_p return value instead of
        building ARRAY_REF on folded VIEW_CONVERT_EXPR to array type.

        * gcc.dg/ubsan/pr79904.c: New test.

--- gcc/internal-fn.c.jj        2017-02-23 08:48:40.000000000 +0100
+++ gcc/internal-fn.c   2017-03-07 11:55:56.261465702 +0100
@@ -1869,12 +1869,20 @@ expand_vector_ubsan_overflow (location_t
       if (cnt > 4)
        {
          tree atype = build_array_type_nelts (eltype, cnt);
-         op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg0);
-         op0 = build4_loc (loc, ARRAY_REF, eltype, op0, cntv,
-                           NULL_TREE, NULL_TREE);
-         op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg1);
-         op1 = build4_loc (loc, ARRAY_REF, eltype, op1, cntv,
-                           NULL_TREE, NULL_TREE);
+         op0 = uniform_vector_p (arg0);
+         if (op0 == NULL_TREE)
+           {
+             op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg0);
+             op0 = build4_loc (loc, ARRAY_REF, eltype, op0, cntv,
+                               NULL_TREE, NULL_TREE);
+           }
+         op1 = uniform_vector_p (arg1);
+         if (op1 == NULL_TREE)
+           {
+             op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, arg1);
+             op1 = build4_loc (loc, ARRAY_REF, eltype, op1, cntv,
+                               NULL_TREE, NULL_TREE);
+           }
          if (resv)
            {
              res = fold_build1_loc (loc, VIEW_CONVERT_EXPR, atype, resv);
--- gcc/testsuite/gcc.dg/ubsan/pr79904.c.jj     2017-03-07 11:58:53.266120958 
+0100
+++ gcc/testsuite/gcc.dg/ubsan/pr79904.c        2017-03-07 11:58:46.000000000 
+0100
@@ -0,0 +1,11 @@
+/* PR sanitizer/79904 */
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=signed-integer-overflow -Wno-psabi" } */
+
+typedef signed char V __attribute__((vector_size (8))); 
+
+void
+foo (V *a) 
+{ 
+  *a = *a * 3; 
+}

        Jakub

Reply via email to