So this is the second part to pr108031.

Originally I thought this was going to be related to Shreya's work on fixing various cost model goofs in the RISC-V backend and that if we fixed the cost modeling that the right things would just happen.  Essentially what I've had her focused on is cases where we have a single cycle ALU insn, but the reported cost is anything but 4.  Lots of these issues have been clustered around embedded extensions, complex RTL for bitmanip instructions, symbolic addresses, etc.  I figured the costing issue with 108031 would be related.

But it'd been a while since I did that very quick triage, so I went back and took a closer look at the behavior inside CSE; that's when it became clear that the LO_SUM expression and related value equivalent were reporting the same cost.  In that scenario CSE (reasonably) chooses to keep things as-is to avoid gratuitous IL changes.

So we need the LO_SUM expression to cost higher than a simple PLUS, even though they both collapse into addi/add insns.  It's not as crazy at it might seem as anytime we can get rid of the LO_SUM form, we're likely going to get rid of the HIGH expression as well.  Other ports cost symbolics much higher and the RISC-V port may want to follow suit at some point, but for now we can just add a single unit to the LO_SUM expression cost and all the right things happen -- hopefully with no fallout.

This has been tested on riscv32-elf and riscv64-elf.  Bootstraps on the K3 and c920 will run overnight, but I don't expect any issues.  Pushing to the trunk.

Jeff



commit 0cfd3de946cedafc0948fe4fde5a015c63b8993c
Author: Jeff Law <[email protected]>
Date:   Thu Aug 13 21:22:57 2026 -0600

    [RISC-V][PR target/108031] Adjust cost of LO_SUM expression slightly
    
    So this is the second part to pr108031.
    
    Originally I thought this was going to be related to Shreya's work on fixing
    various cost model goofs in the RISC-V backend and that if we fixed the cost
    modeling that the right things would just happen.  Essentially what I've had
    her focused on is cases where we have a single cycle ALU insn, but the 
reported
    cost is anything but 4.  Lots of these issues have been clustered around
    embedded extensions, complex RTL for bitmanip instructions, symbolic 
addresses,
    etc.  I figured the costing issue with 108031 would be related.
    
    But it'd been a while since I did that very quick triage, so I went back and
    took a closer look at the behavior inside CSE; that's when it became clear 
that
    the LO_SUM expression and related value equivalent were reporting the same
    cost.  In that scenario CSE (reasonably) chooses to keep things as-is to 
avoid
    gratuitous IL changes.
    
    So we need the LO_SUM expression to cost higher than a simple PLUS, even 
though
    they both collapse into addi/add insns.  It's not as crazy at it might seem 
as
    anytime we can get rid of the LO_SUM form, we're likely going to get rid of 
the
    HIGH expression as well.  Other ports cost symbolics much higher and the 
RISC-V
    port may want to follow suit at some point, but for now we can just add a
    single unit to the LO_SUM expression cost and all the right things happen --
    hopefully with no fallout.
    
    This has been tested on riscv32-elf and riscv64-elf.  Bootstraps on the K3 
and
    c920 will run overnight, but I don't expect any issues.  Pushing to the 
trunk.
    
            PR target/108031
    gcc/
            * config/riscv/riscv.cc (riscv_rtx_costs): Bump the cost of a LO_SUM
            by one unit to encourage use of related values instead of the 
symbolic
            form.
    
    gcc/testsuite
            * gcc.target/riscv/pr108031-2.c: New test.

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index f79b55a0c70..a2a51c019ec 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -4773,8 +4773,17 @@ riscv_rtx_costs (rtx x, machine_mode mode, int 
outer_code, int opno ATTRIBUTE_UN
       return false;
 
     case LO_SUM:
+      /* The +1 at the end is to make this ever-so-slightly more
+        expensive than a simple PLUS to encourage CSE-ing the
+        symbolic expression with related symbolic expressions.
+
+        While both PLUS and LO_SUM will turn into an add insn, if
+        we can convert the LO_SUM to a constant offset from another
+        expression, then we'll be able to eliminate the HIGH
+        insn.  */
       *total = (set_src_cost (XEXP (x, 0), mode, speed)
-               + set_src_cost (XEXP (x, 1), mode, speed));
+               + set_src_cost (XEXP (x, 1), mode, speed)
+               + 1);
       return true;
 
     case LT:
diff --git a/gcc/testsuite/gcc.target/riscv/pr108031-2.c 
b/gcc/testsuite/gcc.target/riscv/pr108031-2.c
new file mode 100644
index 00000000000..423334df8ed
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108031-2.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d " { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mabi=ilp32d " { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+#include "pr108031.c"
+
+/* { dg-final { scan-assembler-times "%hi" 2 } } */
+/* { dg-final { scan-assembler-times "%lo" 2 } } */

Reply via email to