https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107338
Kewen Lin <linkw at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Last reconfirmed| |2022-10-21 Status|UNCONFIRMED |NEW CC| |linkw at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #2 from Kewen Lin <linkw at gcc dot gnu.org> --- Confirmed, this issue is BE specific. vect__ifc__10.14_55 = MEM <vector(8) short unsigned int> [(struct s *)_22]; vect__ifc__10.15_57 = MEM <vector(8) short unsigned int> [(struct s *)_22 + 16B]; vect_perm_even_58 = VEC_PERM_EXPR <vect__ifc__10.14_55, vect__ifc__10.15_57, { 0, 2, 4, 6, 8, 10, 12, 14 }>; vect_patt_7.16_60 = [vec_unpack_hi_expr] vect_perm_even_58; vect_patt_7.16_61 = [vec_unpack_lo_expr] vect_perm_even_58; vect_patt_30.17_63 = vect_patt_7.16_60 & { 15728640, 15728640, 15728640, 15728640 }; vect_patt_30.17_64 = vect_patt_7.16_61 & { 15728640, 15728640, 15728640, 15728640 }; vect_patt_31.18_66 = vect_patt_30.17_63 >> 20; vect_patt_31.18_67 = vect_patt_30.17_64 >> 20; The mask 15728640 (0xF00000) and shifting count 20 look wrong here, the used prec is incorrect, after the hunk /* We move the conversion earlier if the loaded type is smaller than the return type to enable the use of widening loads. */ if (TYPE_PRECISION (TREE_TYPE (container)) < TYPE_PRECISION (ret_type) && !useless_type_conversion_p (TREE_TYPE (container), ret_type)) { pattern_stmt = gimple_build_assign (vect_recog_temp_ssa_var (ret_type), NOP_EXPR, container); container = gimple_get_lhs (pattern_stmt); container_type = TREE_TYPE (container); vectype = get_vectype_for_scalar_type (vinfo, container_type); append_pattern_def_seq (vinfo, stmt_info, pattern_stmt, vectype); } container_type has become to have precision 32. Although due to widening loads the resulted vector element have precision 32, actually the low 16 bis are the data what we want, the prec should use the one before the above adjustment. If I moved the prec calculation ahead of this hunk, the case can pass. diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc index 777ba2f5903..d7893f7f3bd 100644 --- a/gcc/tree-vect-patterns.cc +++ b/gcc/tree-vect-patterns.cc @@ -1925,6 +1925,12 @@ vect_recog_bitfield_ref_pattern (vec_info *vinfo, stmt_vec_info stmt_info, tree container_type = TREE_TYPE (container); tree vectype = get_vectype_for_scalar_type (vinfo, container_type); + unsigned HOST_WIDE_INT shift_n = bit_field_offset (bf_ref).to_constant (); + unsigned HOST_WIDE_INT mask_width = bit_field_size (bf_ref).to_constant (); + unsigned HOST_WIDE_INT prec = tree_to_uhwi (TYPE_SIZE (container_type)); + if (BYTES_BIG_ENDIAN) + shift_n = prec - shift_n - mask_width; + /* We move the conversion earlier if the loaded type is smaller than the return type to enable the use of widening loads. */ if (TYPE_PRECISION (TREE_TYPE (container)) < TYPE_PRECISION (ret_type) @@ -1953,12 +1959,6 @@ vect_recog_bitfield_ref_pattern (vec_info *vinfo, stmt_vec_info stmt_info, shift_first = false; } - unsigned HOST_WIDE_INT shift_n = bit_field_offset (bf_ref).to_constant (); - unsigned HOST_WIDE_INT mask_width = bit_field_size (bf_ref).to_constant (); - unsigned HOST_WIDE_INT prec = tree_to_uhwi (TYPE_SIZE (container_type)); - if (BYTES_BIG_ENDIAN) - shift_n = prec - shift_n - mask_width; - /* If we don't have to shift we only generate the mask, so just fix the code-path to shift_first. */ if (shift_n == 0)