vect: Fix an ICE in vect_recog_mask_conversion_pattern
authorDuan bo <duanbo3@huawei.com>
Mon, 12 Oct 2020 11:32:57 +0000 (12:32 +0100)
committerRichard Sandiford <richard.sandiford@arm.com>
Mon, 12 Oct 2020 11:32:57 +0000 (12:32 +0100)
When processing the cond expression, vect_recog_mask_conversion_pattern
doesn't consider the situation that two operands of rhs1 are different
vectypes, leading to a vect ICE. This patch adds the identification and
handling of the situation to fix the problem.

gcc/ChangeLog:

PR target/96757
* tree-vect-patterns.c (vect_recog_mask_conversion_pattern): Add
the identification and handling of the dropped situation in the
cond expression processing phase.

gcc/testsuite/ChangeLog:

PR target/96757
* gcc.target/aarch64/pr96757.c: New test.

gcc/testsuite/gcc.target/aarch64/pr96757.c [new file with mode: 0644]
gcc/tree-vect-patterns.c

diff --git a/gcc/testsuite/gcc.target/aarch64/pr96757.c b/gcc/testsuite/gcc.target/aarch64/pr96757.c
new file mode 100644 (file)
index 0000000..122e39d
--- /dev/null
@@ -0,0 +1,23 @@
+/* PR target/96757 */
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+short 
+fun1(short i, short j)
+{ 
+  return i * j; 
+}
+
+int 
+fun(int a, int b, int c) 
+{
+  int *v, z, k, m;
+  short f, d;
+  for (int i=0; i<c; i++) 
+  {
+    f= 4 <= d;
+    k= a > m;
+    z = f > k;
+    *v += fun1(z,b);
+  }
+}
index 71e4e10..bc5f2e6 100644 (file)
@@ -4245,6 +4245,8 @@ vect_recog_mask_conversion_pattern (vec_info *vinfo,
   tree lhs = NULL_TREE, rhs1, rhs2, tmp, rhs1_type, rhs2_type;
   tree vectype1, vectype2;
   stmt_vec_info pattern_stmt_info;
+  tree rhs1_op0 = NULL_TREE, rhs1_op1 = NULL_TREE;
+  tree rhs1_op0_type = NULL_TREE, rhs1_op1_type = NULL_TREE;
 
   /* Check for MASK_LOAD ans MASK_STORE calls requiring mask conversion.  */
   if (is_gimple_call (last_stmt)
@@ -4344,9 +4346,37 @@ vect_recog_mask_conversion_pattern (vec_info *vinfo,
 
             it is better for b1 and b2 to use the mask type associated
             with int elements rather bool (byte) elements.  */
-         rhs1_type = integer_type_for_mask (TREE_OPERAND (rhs1, 0), vinfo);
-         if (!rhs1_type)
-           rhs1_type = TREE_TYPE (TREE_OPERAND (rhs1, 0));
+         rhs1_op0 = TREE_OPERAND (rhs1, 0);
+         rhs1_op1 = TREE_OPERAND (rhs1, 1);
+         if (!rhs1_op0 || !rhs1_op1)
+           return NULL;
+         rhs1_op0_type = integer_type_for_mask (rhs1_op0, vinfo);
+         rhs1_op1_type = integer_type_for_mask (rhs1_op1, vinfo);
+
+         if (!rhs1_op0_type)
+           rhs1_type = TREE_TYPE (rhs1_op0);
+         else if (!rhs1_op1_type)
+           rhs1_type = TREE_TYPE (rhs1_op1);
+         else if (TYPE_PRECISION (rhs1_op0_type)
+                  != TYPE_PRECISION (rhs1_op1_type))
+           {
+             int tmp0 = (int) TYPE_PRECISION (rhs1_op0_type)
+                        - (int) TYPE_PRECISION (TREE_TYPE (lhs));
+             int tmp1 = (int) TYPE_PRECISION (rhs1_op1_type)
+                        - (int) TYPE_PRECISION (TREE_TYPE (lhs));
+             if ((tmp0 > 0 && tmp1 > 0) || (tmp0 < 0 && tmp1 < 0))
+               {
+                 if (abs (tmp0) > abs (tmp1))
+                   rhs1_type = rhs1_op1_type;
+                 else
+                   rhs1_type = rhs1_op0_type;
+               }
+             else
+               rhs1_type = build_nonstandard_integer_type
+                 (TYPE_PRECISION (TREE_TYPE (lhs)), 1);
+           }
+         else
+           rhs1_type = rhs1_op0_type;
        }
       else
        return NULL;
@@ -4364,8 +4394,8 @@ vect_recog_mask_conversion_pattern (vec_info *vinfo,
         name from the outset.  */
       if (known_eq (TYPE_VECTOR_SUBPARTS (vectype1),
                    TYPE_VECTOR_SUBPARTS (vectype2))
-         && (TREE_CODE (rhs1) == SSA_NAME
-             || rhs1_type == TREE_TYPE (TREE_OPERAND (rhs1, 0))))
+         && !rhs1_op0_type
+         && !rhs1_op1_type)
        return NULL;
 
       /* If rhs1 is invariant and we can promote it leave the COND_EXPR
@@ -4397,7 +4427,16 @@ vect_recog_mask_conversion_pattern (vec_info *vinfo,
       if (TREE_CODE (rhs1) != SSA_NAME)
        {
          tmp = vect_recog_temp_ssa_var (TREE_TYPE (rhs1), NULL);
-         pattern_stmt = gimple_build_assign (tmp, rhs1);
+         if (rhs1_op0_type
+             && TYPE_PRECISION (rhs1_op0_type) != TYPE_PRECISION (rhs1_type))
+           rhs1_op0 = build_mask_conversion (vinfo, rhs1_op0,
+                                             vectype2, stmt_vinfo);
+         if (rhs1_op1_type
+             && TYPE_PRECISION (rhs1_op1_type) != TYPE_PRECISION (rhs1_type))
+           rhs1_op1 = build_mask_conversion (vinfo, rhs1_op1,
+                                     vectype2, stmt_vinfo);
+         pattern_stmt = gimple_build_assign (tmp, TREE_CODE (rhs1),
+                                             rhs1_op0, rhs1_op1);
          rhs1 = tmp;
          append_pattern_def_seq (vinfo, stmt_vinfo, pattern_stmt, vectype2,
                                  rhs1_type);