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?

Reply via email to