https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82192
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|ASSIGNED |NEW CC| |law at gcc dot gnu.org, | |segher at gcc dot gnu.org Assignee|jakub at gcc dot gnu.org |unassigned at gcc dot gnu.org --- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> --- So, we call make_compound_extraction_int on (and:HI (subreg:HI (lshiftrt:SI (subreg:SI (reg:DI 94 [ a ]) 0) (subreg:QI (reg:SI 97) 0)) 0) (const_int 8191 [0x1fff])) and that calls make_extraction (SImode, (subreg:SI (reg:DI 94 [ a ]) 0), 0, (subreg:QI (reg:SI 97) 0), 13, 1, 0, false); I'm afraid I have no idea what are the requirements/behavior of ZERO_EXTRACT or make_extraction when POS + LEN is bigger than the bitsize of the operand and therefore no idea where the bug is. If there is a requirement that POS + LEN must be always <= bitsize of the operand, then it is invalid to handle LSHIFTRT with variable shift count through make_extraction, because we actually want to extract fewer than LEN bits for some POS values and the rest are 0. If POS + LEN may be larger than bitsize and the remaining bits are zero, then it is invalid to if (GET_CODE (inner) == SUBREG && subreg_lowpart_p (inner)) { /* If going from (subreg:SI (mem:QI ...)) to (mem:QI ...), consider just the QI as the memory to extract from. The subreg adds or removes high bits; its mode is irrelevant to the meaning of this extraction, since POS and LEN count from the lsb. */ if (MEM_P (SUBREG_REG (inner))) is_mode = GET_MODE (SUBREG_REG (inner)); inner = SUBREG_REG (inner); } for non-paradoxical subregs and pos_rtx != NULL_RTX and non-constant or constant, but with POS + LEN larger than original GET_MODE (inner). We can (zero_extract:SI (subreg:SI (reg:DI 94 [ a ]) 0) (const_int 13 [0xd]) (zero_extend:SI (subreg:QI (reg:SI 97) 0))) but not (zero_extract:DI (reg:DI 94 [ a ]) (const_int 13 [0xd]) (zero_extend:SI (subreg:QI (reg:SI 97) 0))) because for the pos_rtx larger than 32-13 the former extracts 12 to 1 bits out of the SImode and zero extends that, while for the latter it always extracts 13 bits out of the 64-bit pseudo.