[llvm] f4ded95 - [RISCV] Support srx/slx for P extension. (#173225)

via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 23 14:17:03 PST 2025


Author: Craig Topper
Date: 2025-12-23T14:16:58-08:00
New Revision: f4ded95b0fa145f87db5bfc9fc2bdf244806fea2

URL: https://github.com/llvm/llvm-project/commit/f4ded95b0fa145f87db5bfc9fc2bdf244806fea2
DIFF: https://github.com/llvm/llvm-project/commit/f4ded95b0fa145f87db5bfc9fc2bdf244806fea2.diff

LOG: [RISCV] Support srx/slx for P extension. (#173225)

These instructions can be used for fshl and fshr respectively.

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVISelLowering.cpp
    llvm/lib/Target/RISCV/RISCVInstrInfoP.td
    llvm/test/CodeGen/RISCV/rv32p.ll
    llvm/test/CodeGen/RISCV/rv64p.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 7dfb5cd0a9e6c..23a24d184e508 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -398,6 +398,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
     setOperationAction({ISD::ROTL, ISD::ROTR}, XLenVT, Expand);
   }
 
+  if (Subtarget.hasStdExtP())
+    setOperationAction({ISD::FSHL, ISD::FSHR}, XLenVT, Legal);
+
   setOperationAction(ISD::BSWAP, XLenVT,
                      Subtarget.hasREV8Like() ? Legal : Expand);
 

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
index 060161f3a8fa0..92a9c06fc534b 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
@@ -690,7 +690,7 @@ let Predicates = [HasStdExtP, IsRV64] in {
 } // Predicates = [HasStdExtP, IsRV64]
 
 let Predicates = [HasStdExtP] in {
-  def SLX          : RVPBinary_rr<0b0001, 0b11, 0b001, "slx">;
+  def SLX          : RVPTernary_rrr<0b0001, 0b11, 0b001, "slx">;
 
   def PMUL_H_B01   : RVPBinary_rr<0b0010, 0b00, 0b001, "pmul.h.b01">;
 
@@ -1474,6 +1474,11 @@ def riscv_pmulhsu : RVSDNode<"PMULHSU", SDT_RISCVPBinOp>;
 let Predicates = [HasStdExtP] in {
   def : PatGpr<abs, ABS>;
 
+  def : Pat<(XLenVT (fshl GPR:$rd, GPR:$rs1, shiftMaskXLen:$rs2)),
+            (SLX GPR:$rd, GPR:$rs1, shiftMaskXLen:$rs2)>;
+  def : Pat<(XLenVT (fshr GPR:$rs1, GPR:$rd, shiftMaskXLen:$rs2)),
+            (SRX GPR:$rd, GPR:$rs1, shiftMaskXLen:$rs2)>;
+
   // Basic 8-bit arithmetic patterns
   def: Pat<(XLenVecI8VT (add GPR:$rs1, GPR:$rs2)), (PADD_B GPR:$rs1, GPR:$rs2)>;
   def: Pat<(XLenVecI8VT (sub GPR:$rs1, GPR:$rs2)), (PSUB_B GPR:$rs1, GPR:$rs2)>;

diff  --git a/llvm/test/CodeGen/RISCV/rv32p.ll b/llvm/test/CodeGen/RISCV/rv32p.ll
index 9e3cbeb787da0..0e1aa18b5a9dc 100644
--- a/llvm/test/CodeGen/RISCV/rv32p.ll
+++ b/llvm/test/CodeGen/RISCV/rv32p.ll
@@ -97,3 +97,52 @@ define i32 @pack_i32_3(i16 zeroext %0, i16 zeroext %1, i32 %2) {
   %8 = add i32 %7, %2
   ret i32 %8
 }
+
+define i64 @slx_i64(i64 %x, i64 %y) {
+; CHECK-LABEL: slx_i64:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    sll a3, a0, a2
+; CHECK-NEXT:    slx a1, a0, a2
+; CHECK-NEXT:    mv a0, a3
+; CHECK-NEXT:    ret
+  %a = and i64 %y, 31
+  %b = shl i64 %x, %a
+  ret i64 %b
+}
+
+define i64 @slxi_i64(i64 %x) {
+; CHECK-LABEL: slxi_i64:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    li a2, 25
+; CHECK-NEXT:    slx a1, a0, a2
+; CHECK-NEXT:    slli a0, a0, 25
+; CHECK-NEXT:    ret
+  %a = shl i64 %x, 25
+  ret i64 %a
+}
+
+define i64 @srx_i64(i64 %x, i64 %y) {
+; CHECK-LABEL: srx_i64:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    srl a3, a1, a2
+; CHECK-NEXT:    srx a0, a1, a2
+; CHECK-NEXT:    mv a1, a3
+; CHECK-NEXT:    ret
+  %a = and i64 %y, 31
+  %b = lshr i64 %x, %a
+  ret i64 %b
+}
+
+; FIXME: Using srx instead of slx would avoid the mv.
+define i64 @srxi_i64(i64 %x) {
+; CHECK-LABEL: srxi_i64:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    mv a2, a1
+; CHECK-NEXT:    li a3, 7
+; CHECK-NEXT:    srli a1, a1, 25
+; CHECK-NEXT:    slx a2, a0, a3
+; CHECK-NEXT:    mv a0, a2
+; CHECK-NEXT:    ret
+  %a = lshr i64 %x, 25
+  ret i64 %a
+}

diff  --git a/llvm/test/CodeGen/RISCV/rv64p.ll b/llvm/test/CodeGen/RISCV/rv64p.ll
index b778b1abde461..0042e2922eaef 100644
--- a/llvm/test/CodeGen/RISCV/rv64p.ll
+++ b/llvm/test/CodeGen/RISCV/rv64p.ll
@@ -138,3 +138,52 @@ define i64 @pack_i64_3(ptr %0, ptr %1) {
   %8 = or i64 %5, %7
   ret i64 %8
 }
+
+define i128 @slx_i128(i128 %x, i128 %y) {
+; CHECK-LABEL: slx_i128:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    sll a3, a0, a2
+; CHECK-NEXT:    slx a1, a0, a2
+; CHECK-NEXT:    mv a0, a3
+; CHECK-NEXT:    ret
+  %a = and i128 %y, 63
+  %b = shl i128 %x, %a
+  ret i128 %b
+}
+
+define i128 @slxi_i128(i128 %x) {
+; CHECK-LABEL: slxi_i128:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    li a2, 49
+; CHECK-NEXT:    slx a1, a0, a2
+; CHECK-NEXT:    slli a0, a0, 49
+; CHECK-NEXT:    ret
+  %a = shl i128 %x, 49
+  ret i128 %a
+}
+
+define i128 @srx_i128(i128 %x, i128 %y) {
+; CHECK-LABEL: srx_i128:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    srl a3, a1, a2
+; CHECK-NEXT:    srx a0, a1, a2
+; CHECK-NEXT:    mv a1, a3
+; CHECK-NEXT:    ret
+  %a = and i128 %y, 63
+  %b = lshr i128 %x, %a
+  ret i128 %b
+}
+
+; FIXME: Using srx instead of slx would avoid the mv.
+define i128 @srxi_i128(i128 %x) {
+; CHECK-LABEL: srxi_i128:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    mv a2, a1
+; CHECK-NEXT:    li a3, 15
+; CHECK-NEXT:    srli a1, a1, 49
+; CHECK-NEXT:    slx a2, a0, a3
+; CHECK-NEXT:    mv a0, a2
+; CHECK-NEXT:    ret
+  %a = lshr i128 %x, 49
+  ret i128 %a
+}


        


More information about the llvm-commits mailing list