https://gcc.gnu.org/g:48ae7b09bc6b61bd383c45c25ddb36224a86c712

commit r17-5347-g48ae7b09bc6b61bd383c45c25ddb36224a86c712
Author: Jeff Law <[email protected]>
Date:   Mon Oct 19 10:01:18 2026 -0600

    [PR target/127865][RISC-V] Refine selection of AOP for RISC-V
    
    So Anton's test showed a case where we'd have been better off steering 
towards
    PLUS for rv64 that had not occurred to me.
    
    In particular if we steer towards PLUS, then we can get sign extensions for
    free via addw/addiw; the sequence doesn't even have to end, they can appear 
in
    the middle of an instruction stream and allow us to eliminate a sign 
extension
    later as evidenced by Anton's test.  So one more reason to steer towards 
PLUS.
    
    This has the potential to make identification of bseti harder.  We'll have 
to
    monitor that and I wouldn't be surprised if final resolution of an AOP op
    really needs to wait until after combine is done.  But that's definitely in 
the
    future work space.
    
    Bootstrapped and regression tested on the k3 and c920.  K1 is in flight.  
Also
    tested on riscv32-elf and riscv64-elf.  Pushing to the trunk.
    
    Assisted-By: LLM for patch review
    
            PR target/127865
    gcc/
            * config/riscv/riscv.md (aop<mode>3): Steer more operations towards
            PLUS for rv64.
    
    gcc/testsuite
    
            * gcc.target/riscv/pr127865.c: New test.

Diff:
---
 gcc/config/riscv/riscv.md                 | 16 +++-------------
 gcc/testsuite/gcc.target/riscv/pr127865.c | 20 ++++++++++++++++++++
 2 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 448bd2415379..da6394d1ae6b 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -5491,21 +5491,11 @@
   {
     /* If we have shift-add insns and arguments are all registers, steer
        towards PLUS, otherwise steer towards IOR.  */
-    if (TARGET_ZBA && REG_P (operands[2]))
+    if ((TARGET_ZBA && REG_P (operands[2]))
+       || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
       emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[2]));
     else
-      {
-       /* We accept GPRs, so we need to do the right thing for SI on rv64.  */
-       if (GET_MODE (operands[0]) != word_mode)
-         {
-           operands[0] = gen_lowpart (word_mode, operands[0]);
-           operands[1] = gen_lowpart (word_mode, operands[1]);
-           operands[2] = gen_lowpart (word_mode, operands[2]);
-           emit_insn (gen_iordi3 (operands[0], operands[1], operands[2]));
-         }
-       else
-         emit_insn (gen_ior<mode>3 (operands[0], operands[1], operands[2]));
-      }
+      emit_insn (gen_ior<mode>3 (operands[0], operands[1], operands[2]));
     DONE;
   }
 ) 
diff --git a/gcc/testsuite/gcc.target/riscv/pr127865.c 
b/gcc/testsuite/gcc.target/riscv/pr127865.c
new file mode 100644
index 000000000000..0dc877238dd7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr127865.c
@@ -0,0 +1,20 @@
+/* { dg-do compile { target rv64 } } */
+/* { dg-skip-if "" { *-*-* } { "-O0"} } */
+
+
+
+unsigned
+f4 (unsigned *p)
+{
+  unsigned s1 = p[0], s2 = p[1];
+  unsigned b = ((s1 << 13) ^ s1) >> 19;
+  s1 = ((s1 & 0xFFFFFFFEU) << 12) ^ b;
+  b = ((s2 << 2) ^ s2) >> 25;
+  s2 = ((s2 & 0xFFFFFFF8U) << 4) ^ b;
+  p[0] = s1;
+  p[1] = s2;
+  return s1 ^ s2;
+}
+
+/* { dg-final { scan-assembler-not "sext.w\t" } } */
+

Reply via email to