aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vect-patterns.c
diff options
context:
space:
mode:
authorDuan bo <duanbo3@huawei.com>2020-10-12 12:32:57 +0100
committerRichard Sandiford <richard.sandiford@arm.com>2020-10-12 12:32:57 +0100
commit91d80cf4bd2827dd9c40fe6a7c719c909d79083d (patch)
tree4a0251704df6535689ca97a985db341f07459c88 /gcc/tree-vect-patterns.c
parent91e4e16b550540723cca824b9674c7d8c43f4849 (diff)
downloadgcc-91d80cf4bd2827dd9c40fe6a7c719c909d79083d.zip
gcc-91d80cf4bd2827dd9c40fe6a7c719c909d79083d.tar.gz
gcc-91d80cf4bd2827dd9c40fe6a7c719c909d79083d.tar.bz2
vect: Fix an ICE in vect_recog_mask_conversion_pattern
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.
Diffstat (limited to 'gcc/tree-vect-patterns.c')
-rw-r--r--gcc/tree-vect-patterns.c51
1 files changed, 45 insertions, 6 deletions
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
index 71e4e10..bc5f2e6 100644
--- a/gcc/tree-vect-patterns.c
+++ b/gcc/tree-vect-patterns.c
@@ -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);