https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119114
--- Comment #20 from Robin Dapp <rdapp at gcc dot gnu.org> ---
Hmm, so right now we return "1" or "0" when extracting from a mask, not "-1" or
"0" and that's what aarch64/SVE does as well. We cannot start returning a
sign-extended -1 all of a sudden.
There is an inconsistency in how we extract those values, though. One way
(e.g. pr114668) is:
tree bftype = TREE_TYPE (vectype);
if (VECTOR_BOOLEAN_TYPE_P (vectype))
bftype = build_nonstandard_integer_type (tree_to_uhwi (bitsize), 1);
new_tree = build3 (BIT_FIELD_REF, bftype, vec_lhs_phi, bitsize,
bitstart);
new_tree = force_gimple_operand (fold_convert (lhs_type, new_tree),
&stmts, true, NULL_TREE);
and the other way (exercised here):
/* SCALAR_RES = VEC_EXTRACT <VEC_LHS, LEN + BIAS - 1>. */
tree scalar_res
= gimple_build (&stmts, CFN_VEC_EXTRACT, TREE_TYPE (vectype),
vec_lhs_phi, last_index);
With the bit-field ref the LHS is an unsigned type <unnamed-unsigned:1> while
with vec_extract we use <boolean-signed:1>.
With a signed return value the simplification I mentioned above happens. I
have been thinking about its preconditions
&& tree_nop_conversion_p (type, TREE_TYPE (@2))
&& types_match (type, @0)
but they seem correct. <boolean-signed:1> and _Bool match?
When using
tree bftype = TREE_TYPE (vectype);
if (VECTOR_BOOLEAN_TYPE_P (vectype))
bftype = build_nonstandard_integer_type (1, 1);
for the VEC_EXTRACT way both test cases work and we don't perform the
simplification. But I haven't done further testing.