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.