https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96757
Bug ID: 96757 Summary: aarch64:ICE during GIMPLE pass: vect Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: duanbo3 at huawei dot com Target Milestone: --- Hi, gcc-trunk ICEs when compiling the following testcase with -O3 on aarch64: 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); } } a.c: In function ‘fun’: a.c:12:1: error: non-trivial conversion in unary operation 12 | fun(int a, int b, int c) | ^~~ vector(4) <signed-boolean:16> vector(4) <signed-boolean:32> mask_patt_29.18_65 = ~mask__2.17_64; during GIMPLE pass: vect dump file: a.c.163t.vect a.c:12:1: internal compiler error: verify_gimple failed 0xcc4767 verify_gimple_in_cfg(function*, bool) .././../gcc/tree-cfg.c:5491 0xb8af2b execute_function_todo .././../gcc/passes.c:1992 0xb8be2b do_per_function .././../gcc/passes.c:1640 0xb8be2b execute_todo .././../gcc/passes.c:2046 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions. Before vect pass, the main statements of this case will be optimized like: _1 = d_10(D) > 3; _2 = a_11(D) > m_12(D); _18 = _1 > _2 ? _26 : 0; At the beginning of vectorization analysis,function vect_recog_mask_conversion_pattern processed the gimple _18 = _1 > _2 ? _15 : 0,and produce such results: patt_17 = _1 > _2 patt_3 = patt_17 ? _15 : 0 However, it didn't consider the situation that _1, _2's vectype is different, So vectorization analysis failed with most of vector mode when examining the statement patt_17 = _1 > _2. Due to aarch64 support vectorizing with multiple vector sizes (https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=74166aabeb7f) , in some special mode, like V4HImode for this case, _1 = d_10(D) > 3 and _2 = a_11(D) > m_12(D) had same nunits but different vectype, which make vectorization analysis succeeded. After that,the statement patt_29 = _1 > _2 was transformed like: mask_patt_29.21_72 = ~mask__2.20_71; mask_patt_29.21_73 = mask__1.19_68 & mask_patt_29.21_72; the vectype of mask__2.20_71 is vector(4) <signed-boolean:32>,the vectype of mask_patt_29.21_72 is vector(4) <signed-boolean:16>, which leading to the ICE. I have prepared the following patch to fix this problem, this patch added the identification and handling for this situation in vect_recog_mask_conversion_pattern. With that _18 = _1 > _2 ? _15 : 0 will be transformed to such statements: patt_3 = (<signed-boolean:16>) _2; patt_17 = _1 > patt_3; patt_20 = patt_17 ? _26 : 0; Bootstrap and tested on both aarch64 and x86 Linux platform, no new regression witnessed. diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 03d50ec5c90..cfd6bfdede8 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -4395,6 +4395,40 @@ vect_recog_mask_conversion_pattern (vec_info *vinfo, { tmp = vect_recog_temp_ssa_var (TREE_TYPE (rhs1), NULL); pattern_stmt = gimple_build_assign (tmp, rhs1); + tree rhs1_op0 = TREE_OPERAND (rhs1, 0); + tree rhs1_op1 = TREE_OPERAND (rhs1, 1); + if (rhs1_op0 && rhs1_op1 + && (TREE_CODE (TREE_TYPE (rhs1_op0)) == BOOLEAN_TYPE) + && (TREE_CODE (TREE_TYPE (rhs1_op1)) == BOOLEAN_TYPE)) + { + tree rhs1_op0_type = integer_type_for_mask (rhs1_op0, vinfo); + tree rhs1_op1_type = integer_type_for_mask (rhs1_op1, vinfo); + enum tree_code rhs1_code = gimple_assign_rhs_code (pattern_stmt); + if (rhs1_op0_type && rhs1_op1_type + && (!(TYPE_PRECISION (rhs1_op0_type) + == TYPE_PRECISION (rhs1_op1_type)))) + { + if (TYPE_PRECISION (rhs1_op0_type) + < TYPE_PRECISION (rhs1_op1_type)) + { + vectype2 + = get_mask_type_for_scalar_type (vinfo, rhs1_op0_type); + if (vectype2) + rhs1_op1 = build_mask_conversion (vinfo, rhs1_op1, + vectype2, stmt_vinfo); + } + else + { + vectype2 + = get_mask_type_for_scalar_type (vinfo, rhs1_op1_type); + if (vectype2) + rhs1_op0 = build_mask_conversion (vinfo, rhs1_op0, + vectype2, stmt_vinfo); + } + pattern_stmt = gimple_build_assign (tmp, rhs1_code, + rhs1_op0, rhs1_op1); + } + } rhs1 = tmp; append_pattern_def_seq (vinfo, stmt_vinfo, pattern_stmt, vectype2, rhs1_type);