https://gcc.gnu.org/g:3ab2199392445f2deb3855dcfe68ecf0fed8466d

commit r17-2456-g3ab2199392445f2deb3855dcfe68ecf0fed8466d
Author: Jeff Law <[email protected]>
Date:   Thu Jul 16 06:37:53 2026 -0600

    [RISC-V] Improve costing for if-converted sequences
    
    So I'm not happy with this entire routine, but after trying to fix things
    right, I'm back to adjusting the cost routine instead.
    
    The fundamental problem as I see it is the cstore patterns on RISC-V are
    suboptimal.
    
    Those patterns always have an SI destination.  One expander is used for 
integer
    inputs, the other for FP inputs.
    
    In both the integer and FP case we use an iterator to allow different input
    modes.  But the destination stays fixed in SI.
    
    But it'd be really advantageous to support an output iterator. With the 
forced
    SI output we typically end up with subreg copies, zero extensions and moves 
in
    sequences involving SCC insns.  That is usually cleaned up by combine, but
    those extra insns participate in if-conversion costing and sometimes cause 
us
    to miss opportunities or force us into a slower/bigger sequence using
    generalized conditional moves.
    
    Of course the cstore only has one mode, which if I read the docs correctly
    *should* be the output mode.  RISC-V is using it for the input modes.  So 
we're
    doing something a bit dumb there.  To achieve that we'd need to combine the 
two
    expanders since they both have integer output modes and we can't have two
    expanders with the same name.  To combine the expanders the inputs have to
    accept both integer and FP modes.  That's likely possible but it's going to 
get
    ugly (for example, use modeless operands and check modes and FAIL in the
    expansion code).
    
    So rather than fight that battle, this patch just ignores the trivial copies
    that can be generated during expansion.  The code was already ignoring 
certain
    extensions and promoted subreg copies.   With some in flight if-conversion 
work
    we're able to take this testcase (adjusted from a loongarch test):
    
    extern long lm, ln, lr;
    
    void
    test_ne ()
    {
      if (lm != ln)
        lr += (1 << 2);
      lr += lm;
    }
    
    Which previously generated this code for the conditional add
    
            beq     a5,a2,.L2
            addi    a4,a4,4
    .L2:
            add     a5,a5,a4
    
    With the in flight if-converter work alone we'd generate:
    
            sub     t2,t0,t1
            li      a1,4
            czero.eqz       a0,a1,t2
            add     a6,a3,a0
            add     a7,t0,a6
    
    It's straightline code and probably better due to that alone if the branch 
has
    meaningful unpredictability for the hardware.  Add in this patch to send us
    through a different if-conversion path and we get:
    
            sub     t2,t0,t1
            snez    a0,t2
            sh2add  a1,a0,a2
            add     a6,t0,a1
    
    For shift counts 1..3 we'll get that shNadd form.  For shift counts 4..11 
we'll
    get sll+add.  For shift counts > 11 the middle block in the if-conversion 
path
    has two insns because the constant can't encode into an addi instruction 
and we
    can't use the specialized ifcvt paths.
    
    Tested on riscv32-elf and riscv64-elf.  Bootstrap & regression test on k3 
is in
    flight.  Bootstrap and regression test and k1 and c920 will fire up later
    today.  Obviously I'll wait for pre-commit CI to render its verdict, I 
expect
    I'll have k3 data by then as well.
    
    gcc/
    
            * config/riscv/riscv.cc (riscv_noce_conversion_profitable_p): Ignore
            reg->reg copies too.

Diff:
---
 gcc/config/riscv/riscv.cc | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 6eeaa11caab2..55567cb281f7 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -5201,6 +5201,12 @@ riscv_noce_conversion_profitable_p (rtx_insn *seq,
              riscv_if_info.original_cost += COSTS_N_INSNS (1);
              riscv_if_info.max_seq_cost += COSTS_N_INSNS (1);
            }
+         else if (REG_P (src) && REG_P (dest))
+           {
+             /* Trivial copies likely just get propagated away.  */
+             riscv_if_info.original_cost += COSTS_N_INSNS (1);
+             riscv_if_info.max_seq_cost += COSTS_N_INSNS (1);
+           }
          else
            last_dest = NULL_RTX;

Reply via email to