https://gcc.gnu.org/g:7274c781e8e0ad113c4a16427b83f7e8b8107c70

commit r16-6441-g7274c781e8e0ad113c4a16427b83f7e8b8107c70
Author: Jeff Law <[email protected]>
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;
+}

Reply via email to