[llvm] [RISCV] Add SATI_RV64/USATI_RV64 to RISCVOptWInstrs. (PR #190030)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 1 12:53:09 PDT 2026


https://github.com/topperc created https://github.com/llvm/llvm-project/pull/190030

Note the immediates for these 2 instructions in their MachineInstr representations both use the type width. The SATI_RV64 binary encoding and the RISCVISD::SATI encoding uses the type width minus one.

Assisted-by: Claude Sonnet 4.5

>From cf58a3ea2fdf201c0cfa36502141dd4563106b76 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Wed, 1 Apr 2026 12:42:21 -0700
Subject: [PATCH 1/2] Pre-commit tests

---
 .../test/CodeGen/RISCV/opt-w-instrs-p-ext.mir | 132 ++++++++++++++++++
 1 file changed, 132 insertions(+)

diff --git a/llvm/test/CodeGen/RISCV/opt-w-instrs-p-ext.mir b/llvm/test/CodeGen/RISCV/opt-w-instrs-p-ext.mir
index b832b89bb0c1d..a83f1ebf86e4d 100644
--- a/llvm/test/CodeGen/RISCV/opt-w-instrs-p-ext.mir
+++ b/llvm/test/CodeGen/RISCV/opt-w-instrs-p-ext.mir
@@ -117,3 +117,135 @@ body:             |
     $x10 = COPY %4
     PseudoRET
 ...
+---
+name:            sati_rv64_sextw_removed_imm16
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10
+
+    ; CHECK-LABEL: name: sati_rv64_sextw_removed_imm16
+    ; CHECK: liveins: $x10
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[SATI_RV64_:%[0-9]+]]:gpr = SATI_RV64 [[COPY]], 16, implicit-def $vxsat
+    ; CHECK-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[SATI_RV64_]], 0
+    ; CHECK-NEXT: $x10 = COPY [[ADDIW]]
+    ; CHECK-NEXT: PseudoRET
+    %0:gpr = COPY $x10
+    ; SATI_RV64 with imm=16 saturates to [-2^15, 2^15-1], which is sign-extended
+    %1:gpr = SATI_RV64 %0, 16, implicit-def $vxsat
+    %2:gpr = ADDIW %1, 0
+    $x10 = COPY %2
+    PseudoRET
+...
+---
+name:            sati_rv64_sextw_removed_imm32
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10
+
+    ; CHECK-LABEL: name: sati_rv64_sextw_removed_imm32
+    ; CHECK: liveins: $x10
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[SATI_RV64_:%[0-9]+]]:gpr = SATI_RV64 [[COPY]], 32, implicit-def $vxsat
+    ; CHECK-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[SATI_RV64_]], 0
+    ; CHECK-NEXT: $x10 = COPY [[ADDIW]]
+    ; CHECK-NEXT: PseudoRET
+    %0:gpr = COPY $x10
+    ; SATI_RV64 with imm=32 saturates to [-2^31, 2^31-1], which is sign-extended
+    %1:gpr = SATI_RV64 %0, 32, implicit-def $vxsat
+    %2:gpr = ADDIW %1, 0
+    $x10 = COPY %2
+    PseudoRET
+...
+---
+name:            sati_rv64_sextw_not_removed_imm33
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10
+
+    ; CHECK-LABEL: name: sati_rv64_sextw_not_removed_imm33
+    ; CHECK: liveins: $x10
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[SATI_RV64_:%[0-9]+]]:gpr = SATI_RV64 [[COPY]], 33, implicit-def $vxsat
+    ; CHECK-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[SATI_RV64_]], 0
+    ; CHECK-NEXT: $x10 = COPY [[ADDIW]]
+    ; CHECK-NEXT: PseudoRET
+    %0:gpr = COPY $x10
+    ; SATI_RV64 with imm=33 saturates to [-2^32, 2^32-1], which is NOT sign-extended from bit 31
+    %1:gpr = SATI_RV64 %0, 33, implicit-def $vxsat
+    %2:gpr = ADDIW %1, 0
+    $x10 = COPY %2
+    PseudoRET
+...
+---
+name:            usati_rv64_sextw_removed_imm16
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10
+
+    ; CHECK-LABEL: name: usati_rv64_sextw_removed_imm16
+    ; CHECK: liveins: $x10
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[USATI_RV64_:%[0-9]+]]:gpr = USATI_RV64 [[COPY]], 16, implicit-def $vxsat
+    ; CHECK-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[USATI_RV64_]], 0
+    ; CHECK-NEXT: $x10 = COPY [[ADDIW]]
+    ; CHECK-NEXT: PseudoRET
+    %0:gpr = COPY $x10
+    ; USATI_RV64 with imm=16 saturates to [0, 2^16-1], which is sign-extended (bit 31 is 0)
+    %1:gpr = USATI_RV64 %0, 16, implicit-def $vxsat
+    %2:gpr = ADDIW %1, 0
+    $x10 = COPY %2
+    PseudoRET
+...
+---
+name:            usati_rv64_sextw_removed_imm31
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10
+
+    ; CHECK-LABEL: name: usati_rv64_sextw_removed_imm31
+    ; CHECK: liveins: $x10
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[USATI_RV64_:%[0-9]+]]:gpr = USATI_RV64 [[COPY]], 31, implicit-def $vxsat
+    ; CHECK-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[USATI_RV64_]], 0
+    ; CHECK-NEXT: $x10 = COPY [[ADDIW]]
+    ; CHECK-NEXT: PseudoRET
+    %0:gpr = COPY $x10
+    ; USATI_RV64 with imm=31 saturates to [0, 2^31-1], which is sign-extended (bit 31 is 0)
+    %1:gpr = USATI_RV64 %0, 31, implicit-def $vxsat
+    %2:gpr = ADDIW %1, 0
+    $x10 = COPY %2
+    PseudoRET
+...
+---
+name:            usati_rv64_sextw_not_removed_imm32
+tracksRegLiveness: true
+body:             |
+  bb.0.entry:
+    liveins: $x10
+
+    ; CHECK-LABEL: name: usati_rv64_sextw_not_removed_imm32
+    ; CHECK: liveins: $x10
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[USATI_RV64_:%[0-9]+]]:gpr = USATI_RV64 [[COPY]], 32, implicit-def $vxsat
+    ; CHECK-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[USATI_RV64_]], 0
+    ; CHECK-NEXT: $x10 = COPY [[ADDIW]]
+    ; CHECK-NEXT: PseudoRET
+    %0:gpr = COPY $x10
+    ; USATI_RV64 with imm=32 saturates to [0, 2^32-1], which is NOT sign-extended from bit 31
+    %1:gpr = USATI_RV64 %0, 32, implicit-def $vxsat
+    %2:gpr = ADDIW %1, 0
+    $x10 = COPY %2
+    PseudoRET
+...

>From eb44fa6d4c06fe36db55e23d19f08f224ce20378 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Wed, 1 Apr 2026 12:47:39 -0700
Subject: [PATCH 2/2] [RISCV] Add SATI_RV64/USATI_RV64 to RISCVOptWInstrs.

Assisted-by: Claude Sonnet 4.5
---
 llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp      |  8 ++++++++
 llvm/test/CodeGen/RISCV/opt-w-instrs-p-ext.mir | 12 ++++--------
 2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp b/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp
index 254a2e2b40b50..bdd6f716302a5 100644
--- a/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp
+++ b/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp
@@ -429,6 +429,14 @@ static bool isSignExtendingOpW(const MachineInstr &MI, unsigned OpNo) {
     unsigned Lsb = MI.getOperand(3).getImm();
     return Msb >= Lsb && (Msb - Lsb + 1) < 32;
   }
+  case RISCV::SATI_RV64:
+    // Saturates to signed range [-2^(imm-1), 2^(imm-1)-1].
+    // If imm <= 32, result fits in 32-bit signed range, thus sign-extended.
+    return MI.getOperand(2).getImm() <= 32;
+  case RISCV::USATI_RV64:
+    // Saturates to unsigned range [0, 2^imm-1].
+    // If imm < 32, result has bit 31 clear, thus sign-extended.
+    return MI.getOperand(2).getImm() < 32;
   }
 
   return false;
diff --git a/llvm/test/CodeGen/RISCV/opt-w-instrs-p-ext.mir b/llvm/test/CodeGen/RISCV/opt-w-instrs-p-ext.mir
index a83f1ebf86e4d..55545fab298d8 100644
--- a/llvm/test/CodeGen/RISCV/opt-w-instrs-p-ext.mir
+++ b/llvm/test/CodeGen/RISCV/opt-w-instrs-p-ext.mir
@@ -129,8 +129,7 @@ body:             |
     ; CHECK-NEXT: {{  $}}
     ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
     ; CHECK-NEXT: [[SATI_RV64_:%[0-9]+]]:gpr = SATI_RV64 [[COPY]], 16, implicit-def $vxsat
-    ; CHECK-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[SATI_RV64_]], 0
-    ; CHECK-NEXT: $x10 = COPY [[ADDIW]]
+    ; CHECK-NEXT: $x10 = COPY [[SATI_RV64_]]
     ; CHECK-NEXT: PseudoRET
     %0:gpr = COPY $x10
     ; SATI_RV64 with imm=16 saturates to [-2^15, 2^15-1], which is sign-extended
@@ -151,8 +150,7 @@ body:             |
     ; CHECK-NEXT: {{  $}}
     ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
     ; CHECK-NEXT: [[SATI_RV64_:%[0-9]+]]:gpr = SATI_RV64 [[COPY]], 32, implicit-def $vxsat
-    ; CHECK-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[SATI_RV64_]], 0
-    ; CHECK-NEXT: $x10 = COPY [[ADDIW]]
+    ; CHECK-NEXT: $x10 = COPY [[SATI_RV64_]]
     ; CHECK-NEXT: PseudoRET
     %0:gpr = COPY $x10
     ; SATI_RV64 with imm=32 saturates to [-2^31, 2^31-1], which is sign-extended
@@ -195,8 +193,7 @@ body:             |
     ; CHECK-NEXT: {{  $}}
     ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
     ; CHECK-NEXT: [[USATI_RV64_:%[0-9]+]]:gpr = USATI_RV64 [[COPY]], 16, implicit-def $vxsat
-    ; CHECK-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[USATI_RV64_]], 0
-    ; CHECK-NEXT: $x10 = COPY [[ADDIW]]
+    ; CHECK-NEXT: $x10 = COPY [[USATI_RV64_]]
     ; CHECK-NEXT: PseudoRET
     %0:gpr = COPY $x10
     ; USATI_RV64 with imm=16 saturates to [0, 2^16-1], which is sign-extended (bit 31 is 0)
@@ -217,8 +214,7 @@ body:             |
     ; CHECK-NEXT: {{  $}}
     ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
     ; CHECK-NEXT: [[USATI_RV64_:%[0-9]+]]:gpr = USATI_RV64 [[COPY]], 31, implicit-def $vxsat
-    ; CHECK-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[USATI_RV64_]], 0
-    ; CHECK-NEXT: $x10 = COPY [[ADDIW]]
+    ; CHECK-NEXT: $x10 = COPY [[USATI_RV64_]]
     ; CHECK-NEXT: PseudoRET
     %0:gpr = COPY $x10
     ; USATI_RV64 with imm=31 saturates to [0, 2^31-1], which is sign-extended (bit 31 is 0)



More information about the llvm-commits mailing list