https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96814
--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> --- So the issue of the miscompile is that we do not expand the vector<bool:1> constructor created by vector lowering correctly. Of course we don't actually _want_ CTORs of those ... The following fixes the miscompile (but will still mishandle vector<bool:1> CTORs concatenating multiple other vector<bool:1>) diff --git a/gcc/expr.c b/gcc/expr.c index 1a15f24b397..8bb3b4caf1c 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -6922,7 +6922,9 @@ store_constructor (tree exp, rtx target, int cleared, poly _int64 size, insn_code icode = CODE_FOR_nothing; tree elt; tree elttype = TREE_TYPE (type); - int elt_size = tree_to_uhwi (TYPE_SIZE (elttype)); + int elt_size + = (VECTOR_BOOLEAN_TYPE_P (type) ? TYPE_PRECISION (elttype) + : tree_to_uhwi (TYPE_SIZE (elttype))); machine_mode eltmode = TYPE_MODE (elttype); HOST_WIDE_INT bitsize; HOST_WIDE_INT bitpos; @@ -7045,7 +7047,9 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size, HOST_WIDE_INT eltpos; tree value = ce->value; - bitsize = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (value))); + bitsize = (VECTOR_BOOLEAN_TYPE_P (type) + ? elt_size + : tree_to_uhwi (TYPE_SIZE (TREE_TYPE (value)))); if (cleared && initializer_zerop (value)) continue; Another interesting case is IMHO typedef unsigned char __attribute__ ((__vector_size__ (32))) V; unsigned char c = 8; int main (void) { V x = ((V){c} > 0) == 0; for (unsigned i = 0; i < sizeof (x); i++) if (x[i] != (i ? 0xff : 0)) __builtin_abort(); return 0; } which shows different behavior of veclower: + vector(32) <signed-boolean:1> _20; + vector(32) <signed-boolean:1> _21; <bb 2> : c.0_1 = c; _11 = {c.0_1}; _2 = _11 != { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - _3 = VEC_COND_EXPR <_2, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }>; + _20 = _11 != { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + _21 = ~_20; + _3 = _21; _4 = VEC_COND_EXPR <_3, { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }>; it shows that while the initial FE IL has the nested VEC_COND (maybe avoid that for boolean vectors?) we fold one case but not the other?