https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89195
--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> --- While I can see how doing - (HOST_WIDE_INT) len instead of - len fixes the ICE, I wonder if what make_extraction does isn't invalid. In particular, we have later on: /* Unless INNER is not MEM, reject this if we would be spanning bytes or if the position is not a constant and the length is not 1. In all other cases, we would only be going outside our object in cases when an original shift would have been undefined. */ if (MEM_P (inner) && ((pos_rtx == 0 && maybe_gt (pos + len, GET_MODE_PRECISION (is_mode))) || (pos_rtx != 0 && len != 1))) return 0; and I think we need this !maybe_gt (pos + len, GET_MODE_PRECISION (is_mode))) even in the: || (MEM_P (inner) && pos_rtx == 0 && (pos % (STRICT_ALIGNMENT ? GET_MODE_ALIGNMENT (tmode) : BITS_PER_UNIT)) == 0 /* We can't do this if we are widening INNER_MODE (it may not be aligned, for one thing). */ && !paradoxical_subreg_p (tmode, inner_mode) && (inner_mode == tmode || (! mode_dependent_address_p (XEXP (inner, 0), MEM_ADDR_SPACE (inner)) && ! MEM_VOLATILE_P (inner)))))) conditions, because otherwise we have a MEM and we try to read some other bytes outside of that MEM, but those might not be accessible at all etc. So, add && known_le (pos + len, GET_MODE_PRECISION (is_mode)) here?