https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96879
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> --- This is an aarch64 backend bug (I needed -fno-section-anchors to trigger though). aarch64_expand_mov_immediate has: case SYMBOL_FORCE_TO_MEM: if (const_offset != 0 && targetm.cannot_force_const_mem (int_mode, imm)) { gcc_assert (can_create_pseudo_p ()); base = aarch64_force_temporary (int_mode, dest, base); aarch64_add_offset (int_mode, dest, base, const_offset, NULL_RTX, NULL_RTX, false); return; } mem = force_const_mem (ptr_mode, imm); gcc_assert (mem); and is called with int_mode DImode and imm is a DImode SYMBOL_REF. As ptr_mode is SImode, the call to force_const_mem is invalid: /* Given a constant rtx X, make (or find) a memory constant for its value and return a MEM rtx to refer to it in memory. IN_MODE is the mode of X. */ In particular, IN_MODE is not the mode of X in this case (the reason for the mode is only for the case of VOIDmode constants). So, either force_const_mem should be called with lowpart_subreg of imm if ptr_mode != int_mode, or it should be called with int_mode instead of ptr_mode and then the later ZERO_EXTEND should not be done. As it seems before my constant pool optimizations such bogus constant pool entry assembled into .word the_immediate, doing a lowpart subreg is probably the right way to go. So perhaps: --- gcc/config/aarch64/aarch64.c.jj 2020-08-24 10:00:01.299258763 +0200 +++ gcc/config/aarch64/aarch64.c 2020-09-01 10:34:50.096468522 +0200 @@ -5131,6 +5131,7 @@ aarch64_expand_mov_immediate (rtx dest, return; } + imm = lowpart_subreg (ptr_mode, imm, int_mode); mem = force_const_mem (ptr_mode, imm); gcc_assert (mem); except I don't know if it will handle the (const:DI (symbol_ref:DI whatever) (const_int 32)) case properly. Also, few lines above this the targetm.cannot_force_const_mem call using int_mode rather than ptr_mode when it later uses ptr_mode is kind of weird.