https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127778
Jeffrey A. Law <law at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Last reconfirmed| |2026-10-09
Ever confirmed|0 |1
Status|UNCONFIRMED |NEW
--- Comment #1 from Jeffrey A. Law <law at gcc dot gnu.org> ---
This would seem to be a failure to expand into a sensible sequence during
initial RTL generation. We generate this in the .expand dump:
(insn 7 4 8 2 (set (reg:DI 136)
(const_int 4096 [0x1000])) "j.c":4:11 -1
(nil))
(insn 8 7 9 2 (set (reg/f:DI 137)
(plus:DI (reg/v/f:DI 134 [ p ])
(reg:DI 136))) "j.c":4:11 -1
(nil))
(insn 9 8 0 2 (set (mem:SI (plus:DI (reg/f:DI 137)
(const_int -96 [0xffffffffffffffa0])) [1 MEM[(int *)p_1(D) +
4000B]+0 S4 A32])
(subreg/s/u:SI (reg/v:DI 135 [ v ]) 0)) "j.c":4:11 -1
(nil))
We should have generated the more efficient form at initial RTL generation
rather than trying to recover it later in the RTL optimization pipeline.
That's generally a much better solution than define_insn_and_split. The core
problem with define_insn_and_split is that it bypasses combine's costing
mechanisms and ultimately tends to force further work to be implemented as a
define_insn_and_split as well.
We've been actively working to remove define_insn_and_split from the port. The
most effective means has been to get the initial RTL generation more sensible
which in turns makes everything in the RTL pipeline work better.
Anyway, it looks like things go wrong inside riscv_legitimize_address or its
children from a very quick debugging session. Essentially the call to
riscv_add_offset is bypassing the adddi3 expander and its synthesize_add call
which knows how to generate better initial RTL.
8 0x00000000022144ed in riscv_legitimize_address (x=0x7ffff73ec618,
oldx=0x7ffff73ec618, mode=E_SImode)
at /home/jlaw/test/gcc/gcc/config/riscv/riscv.cc:3613
3613 addr = riscv_add_offset (NULL, base, offset);
(gdb) p debug_rtx (base)
(reg/v/f:DI 134 [ p ])
$10 = void
(gdb) p offset
$11 = 4000
That riscv_add_offset ends up forcing 4000 into a pseudo, then adding that
pseudo to r134. Getting that passing through adddi3/addsi3 and synthesize_add
should really be the goal here.