]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[RISC-V][PR target/123318] Use a Pmode temporary for output of auipc
authorJeff Law <jeffrey.law@oss.qualcomm.com>
Tue, 30 Dec 2025 17:38:07 +0000 (10:38 -0700)
committerJeff Law <jeffrey.law@oss.qualcomm.com>
Tue, 30 Dec 2025 17:38:07 +0000 (10:38 -0700)
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.

gcc/config/riscv/riscv.cc
gcc/testsuite/gcc.target/riscv/pr123318.c [new file with mode: 0644]

index 617b38ed6d0621ac76d9fbe6ce9ea3381bed4150..4726ac506613efee0bc4697a33669f740762cb79 100644 (file)
@@ -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 (file)
index 0000000..3a1972c
--- /dev/null
@@ -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;
+}