https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96814

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
It's indeed odd that we have a VEC_COND_EXPR creating a boolean vector.  With
GCC 10 veclower saw

  _1 = { 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 };
  _2 = VEC_COND_EXPR <_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, -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 }>;

and _2 is vector<char> while _1 is vector<bool> now we have

  _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 };
  _2 = VEC_COND_EXPR <_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 }, { -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 }>;
  _3 = VEC_COND_EXPR <_2, { -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 }>;

where _2 is vector<bool>, appearantly inverting _1.  This is either
new or missed folding I guess (I see this in .original already).

Now, veclower better shouldn't touch this - definitely a vector<bool>
ctor from SSA names isn't something we want...   Though in principle
we should generate correct code here or give up.

So I'd say we hit a latent issue here?

I see we're doing a bad job in constant folding as well, mostly because
our representation of vector<boolean:1> is special:

 <vector_cst 0x7ffff66572d0
    type <vector_type 0x7ffff6647348
        type <boolean_type 0x7ffff66472a0 public QI
            size <integer_cst 0x7ffff680cdc8 constant 8>
            unit-size <integer_cst 0x7ffff680cde0 constant 1>
            align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7ffff66472a0 precision:1 min <integer_cst 0x7ffff690d300 -1> max <integer_cst
0x7ffff6657258 0>>
        SI
        size <integer_cst 0x7ffff680cf18 constant 32>
        unit-size <integer_cst 0x7ffff680cf30 constant 4>
        align:32 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7ffff6647348 nunits:32>
    constant npatterns:1 nelts-per-pattern:1
    elt:0:  <integer_cst 0x7ffff6657258 type <boolean_type 0x7ffff66472a0>
constant 0>>

see how we're having a vector type of a QImode boolean with size 8.
The folding code assumes it can work with TYPE_SIZE of the component:

    case BIT_FIELD_REF:
      if (TREE_CODE (arg0) == VECTOR_CST
          && (type == TREE_TYPE (TREE_TYPE (arg0))
              || (VECTOR_TYPE_P (type)
                  && TREE_TYPE (type) == TREE_TYPE (TREE_TYPE (arg0))))
          && tree_fits_uhwi_p (op1)
          && tree_fits_uhwi_p (op2))
        {
          tree eltype = TREE_TYPE (TREE_TYPE (arg0));
          unsigned HOST_WIDE_INT width = tree_to_uhwi (TYPE_SIZE (eltype));
          unsigned HOST_WIDE_INT n = tree_to_uhwi (arg1);

but that's not true for these types.

diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 1f861630225..0cc80adf632 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -12581,7 +12581,9 @@ fold_ternary_loc (location_t loc, enum tree_code code,
t
ree type,
          && tree_fits_uhwi_p (op2))
        {
          tree eltype = TREE_TYPE (TREE_TYPE (arg0));
-         unsigned HOST_WIDE_INT width = tree_to_uhwi (TYPE_SIZE (eltype));
+         unsigned HOST_WIDE_INT width
+           = (TREE_CODE (eltype) == BOOLEAN_TYPE
+              ? TYPE_PRECISION (eltype) : tree_to_uhwi (TYPE_SIZE (eltype)));
          unsigned HOST_WIDE_INT n = tree_to_uhwi (arg1);
          unsigned HOST_WIDE_INT idx = tree_to_uhwi (op2);

diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
index 6d5d65195ae..e9dbe07dccc 100644
--- a/gcc/tree-vect-generic.c
+++ b/gcc/tree-vect-generic.c
@@ -137,7 +137,7 @@ tree_vec_extract (gimple_stmt_iterator *gsi, tree type,
     }
   if (bitpos)
     {
-      if (TREE_CODE (type) == BOOLEAN_TYPE)
+      if (0 && TREE_CODE (type) == BOOLEAN_TYPE)
        {
          tree itype
            = build_nonstandard_integer_type (tree_to_uhwi (bitsize), 0);


makes the generated code a bit easier to follow but I guess still ends up
miscompiling things?

Note if I add -fdisable-tree-veclower ISEL ICEs.

So I'd see where this VEC_COND_EXPR comes from.

Reply via email to