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

--- Comment #13 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Christophe Lyon from comment #12)
> (In reply to Jakub Jelinek from comment #11)
> > So, tried this under the debugger.  All VALID_MVE_PRED_MODE modes have the
> > same size, 2 bytes, so I'd go with
> >   else if (VALID_MVE_PRED_MODE (mode))
> >     {
> >       /* unsigned short arguments to functions get promoted to int, undo
> > that.  */
> >       if (GET_MODE_SIZE (x) != GET_MODE_SIZE (HImode))
> >         x = gen_lowpart (HImode, x);
> >       if (GET_MODE (x) != mode)
> >         {
> >           /* Nested SUBREGs are invalid.  */
> >           if (SUBREG_P (x))
> >             x = force_reg (GET_MODE (x), x);
> >           x = lowpart_subreg (mode, x,
> >                               GET_MODE (x) == VOIDmode ? HImode : GET_MODE
> > (x));
> 
> This still crashes with mode == V*BI, because we reach
> rtx_vector_builder::find_cached_value() where elt is not a supported
> constant.

Ah, I was testing just V16BImode and V8BImode, with V16BImode even just
gen_lowpart
on
(const_int -13108 [0xffffffffffffcccc]) works and gives
(const_vector:V16BI [
        (const_int 0 [0]) repeated x2
        (const_int 1 [0x1]) repeated x2
        (const_int 0 [0]) repeated x2
        (const_int 1 [0x1]) repeated x2
        (const_int 0 [0]) repeated x2
        (const_int 1 [0x1]) repeated x2
        (const_int 0 [0]) repeated x2
        (const_int 1 [0x1]) repeated x2
    ])
while for V8BImode it gives
(const_vector:V8BI [
        (const_int 0 [0])
        (const_int -1 [0xffffffffffffffff])
        (const_int 0 [0])
        (const_int -1 [0xffffffffffffffff])
        (const_int 0 [0])
        (const_int -1 [0xffffffffffffffff])
        (const_int 0 [0])
        (const_int -1 [0xffffffffffffffff])
    ])
Now, the question is what these weird B2Imode and B4Imode modes are about.
Are they really 2bit and 4bit booleans, with 0 being false, some value (1 or
all ones?) true, everything else UB?  Something else?
The 0xcccc when it is 1 bit per element indeed is what the above V16BImode
CONST_VECTOR is, the 0xcccc with 2 bits per element is 0 or -1 (but, shouldn't
that be UB?),
but with 0xcccc with 4 bits per element it is element 0xc, that doesn't feel
right
for a boolean in any case.
native_decode_vector_rtx for the bool vectors does:
          unsigned int bit_index = first_byte * BITS_PER_UNIT + i * elt_bits;
          unsigned int byte_index = bit_index / BITS_PER_UNIT;
          unsigned int lsb = bit_index % BITS_PER_UNIT;
          unsigned int value = bytes[byte_index] >> lsb;
          builder.quick_push (gen_int_mode (value, GET_MODE_INNER (mode)));
and kind of expects that gen_int_mode canonicalizes it to some boolean value
(apparently it can handle both all ones and 1 as true, but not other values).
93            if (elt == const1_rtx)
94              return CONST1_RTX (m_mode);
95            else if (elt == constm1_rtx)
96              return CONSTM1_RTX (m_mode);
97            else if (elt == const0_rtx)
98              return CONST0_RTX (m_mode);
99            else
100             gcc_unreachable ();
Guess you can get similar ICE for V8BImode if some 2 bit pair is 2 (3 and 1 are
considered true, one of them -1, another 1) and 0 is false;
and for V4BImode obviously far more invalid values.
If the CPU somehow canonicalizes, say any non-zero 2-bit pair (or 4-bit pair)
is considered true (or say decide just based on most significant or least
significant bit), then perhaps you need to do that canonicalization by hand.

Reply via email to