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.