https://gcc.gnu.org/g:1384d5ed1a80d2089bd7d13815e401c26cf26c9a

commit 1384d5ed1a80d2089bd7d13815e401c26cf26c9a
Author: Jeff Law <j...@ventanamicro.com>
Date:   Wed May 21 14:15:23 2025 -0600

    [RISC-V][PR target/120368] Fix 32bit shift on rv64
    
    So a followup to last week's bugfix.  In last week's change we we stopped 
using
    define_insn_and_split to rewrite instructions.  That change was done to 
avoid
    dropping a masking instruction out of the RTL.
    
    As a result the pattern(s) were changed into simple define_insns, which is
    good.  One of them uses the GPR iterator since it's supposed to work for 
both
    32bit and 64bit shifts on rv64.
    
    But we failed to emit the right opcode for a 32bit shift on rv64. Thankfully
    the fix is trivial.  If the mode is anything but word_mode, then we must be
    doing a 32-bit shift on rv64, ie the various "w" shift instructions.
    
    It's run through my tester.  Just waiting on the upstream CI system to spin 
it.
    
            PR target/120368
    gcc/
            * config/riscv/riscv.md (shift with masked shift count): Fix
            opcode when generating an SImode shift on rv64.
    
    gcc/testsuite/
            * gcc.target/riscv/pr120368.c: New test.
    
    (cherry picked from commit 8459c546197dc9178d250994db021b36405f1bd6)

Diff:
---
 gcc/config/riscv/riscv.md                 |  9 ++++++++-
 gcc/testsuite/gcc.target/riscv/pr120368.c | 19 +++++++++++++++++++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 7f6d0bbab3eb..7e35d7877ed9 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -2938,7 +2938,14 @@
               (match_operand:GPR2 2 "register_operand"  "r")
               (match_operand 3 "<GPR:shiftm1>"))])))]
   ""
-  "<insn>\t%0,%1,%2"
+{
+  /* If the shift mode is not word mode, then it must be the
+     case that we're generating rv64 code, but this is a 32-bit
+     operation.  Thus we need to use the "w" variant.  */
+  if (E_<GPR:MODE>mode != word_mode)
+    return "<insn>w\t%0,%1,%2";
+  return "<insn>\t%0,%1,%2";
+}
   [(set_attr "type" "shift")
    (set_attr "mode" "<GPR:MODE>")])
 
diff --git a/gcc/testsuite/gcc.target/riscv/pr120368.c 
b/gcc/testsuite/gcc.target/riscv/pr120368.c
new file mode 100644
index 000000000000..4fea8e6fe7c4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr120368.c
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+
+int g;
+
+int
+foo (int s, int v)
+{
+  __builtin_memset (&g, v >> (s & 31), sizeof(g));
+  return g;
+}
+
+int
+main ()
+{
+  int x = foo (-16, 0xdffff);
+  if (x != 0x0d0d0d0d)
+    __builtin_abort();
+  __builtin_exit (0);
+}

Reply via email to