In config/s390/s390.c we accept addresses that are SImode: if (!REG_P (base) || (GET_MODE (base) != SImode && GET_MODE (base) != Pmode)) return false;
However, there doesn't seem to be anything in the s390's opcodes that masks the top half of address registers in 64-bit mode, the SImode convention seems to just be a convention for addresses in the first 4Gb. So... what happens if gcc uses a subreg to load the lower half of a register (via LR), leaving the upper half with random bits in it, then uses that register as an address? I could see no code that checked for this, and I have a fairly large and ungainly test case that says it breaks :-( My local solution was to just disallow "SImode" as an address in s390_decompose_address, which forces gcc to do an explicit SI->DI conversion to clear the upper bits, and it seems to work, but I wonder if it's the ideal solution...