https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114801
--- Comment #7 from Christophe Lyon <clyon at gcc dot gnu.org> --- (In reply to Jakub Jelinek from comment #4) > (In reply to Christophe Lyon from comment #3) > > lowpart_subreg does not work either. > > > > If we put the predicates in a variable in the testcase, then in > > function_expander::add_input_operand() x is already a (subreg/s/v:HI (reg:SI > > 116 [ _3 ]) 0) so taking gen_lowpart of that is OK (we just want HImode to > > get the 16 bits of predicates). > > If x could be e.g. (subreg:SI (reg:DI ...) ...), then one needs to use for > GET_CODE (x) == SUBREG && GET_MODE (x) != mode do a force_reg first. > No sure I got this right: if (GET_CODE (x) == SUBREG && GET_MODE (x) != mode) x = force_reg (mode, x); breaks the assert in emit_move_insn because mode is V4BImode and 'y' is HImode. > > But when predicates are passed as a constant as in the testcase, we have > > x = (const_int -13108 [0xffffffffffffcccc]) > > and gen_lowpart (HImode, x) fails on that. > > Why doesn't lowpart_subreg (mode, x, GET_MODE (x) == VOIDmode ? DImode : > GET_MODE (x)); > work? > I.e. for CONST_INTs assume it is some constant in a mode equal or wider than > mode. > Unless mode can be TImode or x can be __int128 constants, that is. > This fails because down the call chain from lowpart_subreg, we reach gcc_unreachable in rtx_vector_builder::find_cached_value because m_mode == V4BImode (so is MODE_VECTOR_BOOL), but is not a valid expected boolean constant vector.