[gcc r16-6441] [RISC-V][PR target/123318] Use a Pmode temporary for output of auipc
Jeff Law
law@gcc.gnu.org
Tue Dec 30 17:39:25 GMT 2025
https://gcc.gnu.org/g:7274c781e8e0ad113c4a16427b83f7e8b8107c70
commit r16-6441-g7274c781e8e0ad113c4a16427b83f7e8b8107c70
Author: Jeff Law <jeffrey.law@oss.qualcomm.com>
Date: Tue Dec 30 10:38:07 2025 -0700
[RISC-V][PR target/123318] Use a Pmode temporary for output of auipc
In the explict-relocs path through the RISC-V backend we generate sequences
using auipc which stores its result in a GPR.
Under the right circumstances we can end up with cases where we try to use
pseudos which may not be Pmode sized or worse yet may be a floating point mode.
This patch forces those paths to generate a fresh temporary when the provided
one isn't already Pmode. That helps this bug, but I'm not 100% convinced the
explict-relocs stuff is correct and I wouldn't be surprised to find other bugs
lurking in here.
Bootstrapped & regression tested on the Pioneer and regression tested on
riscv{32,64}-elf as well.
Will commit once pre-commit CI gives it the green light.
PR target/123318
gcc/
* config/riscv/riscv.cc (riscv_legitimize_const_move): Force
riscv_split_symbol to generate a new temporary if the provided
one isn't Pmode.
gcc/testsuite/
* gcc.target/riscv/pr123318.c: New test.
Diff:
---
gcc/config/riscv/riscv.cc | 7 +++++--
gcc/testsuite/gcc.target/riscv/pr123318.c | 12 ++++++++++++
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 617b38ed6d06..4726ac506613 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -3440,8 +3440,11 @@ riscv_legitimize_const_move (machine_mode mode, rtx dest, rtx src)
src = force_const_mem (mode, src);
/* When using explicit relocs, constant pool references are sometimes
- not legitimate addresses. */
- riscv_split_symbol (dest, XEXP (src, 0), mode, &XEXP (src, 0));
+ not legitimate addresses. If DEST is not a suitable register (ie,
+ not a Pmode pseudo), then let RISCV_SPLIT_SYMBOL generate a fresh
+ temporary. */
+ riscv_split_symbol (GET_MODE (dest) == Pmode ? dest : NULL_RTX,
+ XEXP (src, 0), mode, &XEXP (src, 0));
riscv_emit_move (dest, src);
}
diff --git a/gcc/testsuite/gcc.target/riscv/pr123318.c b/gcc/testsuite/gcc.target/riscv/pr123318.c
new file mode 100644
index 000000000000..3a1972c996c7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr123318.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target rv64 } } */
+/* { dg-options "-Ofast -mcmodel=medany -mexplicit-relocs -march=rv64gv" } */
+typedef _Complex _Float16 CF;
+_Complex int ci;
+CF cf;
+
+void
+foo()
+{
+ ci += cf;
+ ci -= (CF)0;
+}
More information about the Gcc-cvs
mailing list