[llvm] [RISCV] Support srx/slx for P extension. (PR #173225)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 22 00:06:53 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
Author: Craig Topper (topperc)
<details>
<summary>Changes</summary>
These instructions can be used for fshl and fshr respectively.
---
Full diff: https://github.com/llvm/llvm-project/pull/173225.diff
4 Files Affected:
- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+3)
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoP.td (+6-1)
- (modified) llvm/test/CodeGen/RISCV/rv32p.ll (+49)
- (modified) llvm/test/CodeGen/RISCV/rv64p.ll (+49)
``````````diff
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 c9111a1a24f98..6be18e25086e8 100644
--- a/llvm/test/CodeGen/RISCV/rv32p.ll
+++ b/llvm/test/CodeGen/RISCV/rv32p.ll
@@ -60,3 +60,52 @@ define void @pli_b_store_i32(ptr %p) {
store i32 u0x41414141, ptr %p
ret void
}
+
+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 22dba6501f68c..39902dec66e64 100644
--- a/llvm/test/CodeGen/RISCV/rv64p.ll
+++ b/llvm/test/CodeGen/RISCV/rv64p.ll
@@ -99,3 +99,52 @@ define void @pli_b_store_i32(ptr %p) {
store i32 u0x41414141, ptr %p
ret void
}
+
+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
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/173225
More information about the llvm-commits
mailing list