[llvm] [RISCV][llvm] Support vselect codegen for P extension (PR #175744)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 13 09:10:33 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
Author: Brandon Wu (4vtomat)
<details>
<summary>Changes</summary>
The only difference between vselect vs. select is condition value(a.k.a.
mask), we can select by using bitwise operation:
vselect(mask, true, false) = (mask & true) | (~mask & false)
---
Full diff: https://github.com/llvm/llvm-project/pull/175744.diff
3 Files Affected:
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoP.td (+10)
- (modified) llvm/test/CodeGen/RISCV/rvp-ext-rv32.ll (+39)
- (modified) llvm/test/CodeGen/RISCV/rvp-ext-rv64.ll (+58)
``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
index e97e9a0139e47..30672458d78e8 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
@@ -1645,6 +1645,12 @@ let Predicates = [HasStdExtP] in {
def: Pat<(XLenVecI8VT (umax GPR:$rs1, GPR:$rs2)), (PMAXU_B GPR:$rs1, GPR:$rs2)>;
def: Pat<(XLenVecI16VT (smax GPR:$rs1, GPR:$rs2)), (PMAX_H GPR:$rs1, GPR:$rs2)>;
def: Pat<(XLenVecI16VT (umax GPR:$rs1, GPR:$rs2)), (PMAXU_H GPR:$rs1, GPR:$rs2)>;
+
+ // 8/16-bit vselect patterns
+ def: Pat<(XLenVecI8VT (vselect (XLenVecI8VT GPR:$mask), GPR:$true_v, GPR:$false_v)),
+ (MERGE GPR:$mask, GPR:$false_v, GPR:$true_v)>;
+ def: Pat<(XLenVecI16VT (vselect (XLenVecI16VT GPR:$mask), GPR:$true_v, GPR:$false_v)),
+ (MERGE GPR:$mask, GPR:$false_v, GPR:$true_v)>;
} // Predicates = [HasStdExtP]
let Predicates = [HasStdExtP, IsRV32] in {
@@ -1773,6 +1779,10 @@ let Predicates = [HasStdExtP, IsRV64] in {
def: Pat<(v2i32 (sshlsat GPR:$rs1, (v2i32 (splat_vector uimm5:$shamt)))),
(PSSLAI_W GPR:$rs1, uimm5:$shamt)>;
+ // 32-bit vselect patterns
+ def: Pat<(v2i32 (vselect (v2i32 GPR:$mask), GPR:$true_v, GPR:$false_v)),
+ (MERGE GPR:$mask, GPR:$false_v, GPR:$true_v)>;
+
// Load/Store patterns
def : StPat<store, SD, GPR, v8i8>;
def : StPat<store, SD, GPR, v4i16>;
diff --git a/llvm/test/CodeGen/RISCV/rvp-ext-rv32.ll b/llvm/test/CodeGen/RISCV/rvp-ext-rv32.ll
index 99b551d1a93fa..63a24cbd7aedc 100644
--- a/llvm/test/CodeGen/RISCV/rvp-ext-rv32.ll
+++ b/llvm/test/CodeGen/RISCV/rvp-ext-rv32.ll
@@ -2313,3 +2313,42 @@ define void @test_umax_b(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {
store <4 x i8> %max, ptr %ret_ptr
ret void
}
+
+; Test vselect operations
+define void @test_vselect_v2i16(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr, ptr %c_ptr) {
+; CHECK-LABEL: test_vselect_v2i16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lw a1, 0(a1)
+; CHECK-NEXT: lw a2, 0(a2)
+; CHECK-NEXT: lw a3, 0(a3)
+; CHECK-NEXT: pmslt.h a1, a2, a1
+; CHECK-NEXT: merge a1, a2, a3
+; CHECK-NEXT: sw a1, 0(a0)
+; CHECK-NEXT: ret
+ %a = load <2 x i16>, ptr %a_ptr
+ %b = load <2 x i16>, ptr %b_ptr
+ %c = load <2 x i16>, ptr %c_ptr
+ %mask = icmp sgt <2 x i16> %a, %b
+ %res = select <2 x i1> %mask, <2 x i16> %c, <2 x i16> %b
+ store <2 x i16> %res, ptr %ret_ptr
+ ret void
+}
+
+define void @test_vselect_v4i8(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr, ptr %c_ptr) {
+; CHECK-LABEL: test_vselect_v4i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lw a1, 0(a1)
+; CHECK-NEXT: lw a2, 0(a2)
+; CHECK-NEXT: lw a3, 0(a3)
+; CHECK-NEXT: pmseq.b a1, a1, a2
+; CHECK-NEXT: merge a1, a2, a3
+; CHECK-NEXT: sw a1, 0(a0)
+; CHECK-NEXT: ret
+ %a = load <4 x i8>, ptr %a_ptr
+ %b = load <4 x i8>, ptr %b_ptr
+ %c = load <4 x i8>, ptr %c_ptr
+ %mask = icmp eq <4 x i8> %a, %b
+ %res = select <4 x i1> %mask, <4 x i8> %c, <4 x i8> %b
+ store <4 x i8> %res, ptr %ret_ptr
+ ret void
+}
diff --git a/llvm/test/CodeGen/RISCV/rvp-ext-rv64.ll b/llvm/test/CodeGen/RISCV/rvp-ext-rv64.ll
index 93ca54c5ddb1d..09904f35b8c90 100644
--- a/llvm/test/CodeGen/RISCV/rvp-ext-rv64.ll
+++ b/llvm/test/CodeGen/RISCV/rvp-ext-rv64.ll
@@ -2796,3 +2796,61 @@ define void @test_umax_w(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr) {
store <2 x i32> %max, ptr %ret_ptr
ret void
}
+
+; Test vselect operations
+define void @test_vselect_v4i16(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr, ptr %c_ptr) {
+; CHECK-LABEL: test_vselect_v4i16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: ld a1, 0(a1)
+; CHECK-NEXT: ld a2, 0(a2)
+; CHECK-NEXT: ld a3, 0(a3)
+; CHECK-NEXT: pmseq.h a1, a1, a2
+; CHECK-NEXT: merge a1, a2, a3
+; CHECK-NEXT: sd a1, 0(a0)
+; CHECK-NEXT: ret
+ %a = load <4 x i16>, ptr %a_ptr
+ %b = load <4 x i16>, ptr %b_ptr
+ %c = load <4 x i16>, ptr %c_ptr
+ %mask = icmp eq <4 x i16> %a, %b
+ %res = select <4 x i1> %mask, <4 x i16> %c, <4 x i16> %b
+ store <4 x i16> %res, ptr %ret_ptr
+ ret void
+}
+
+define void @test_vselect_v8i8(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr, ptr %c_ptr) {
+; CHECK-LABEL: test_vselect_v8i8:
+; CHECK: # %bb.0:
+; CHECK-NEXT: ld a1, 0(a1)
+; CHECK-NEXT: ld a2, 0(a2)
+; CHECK-NEXT: ld a3, 0(a3)
+; CHECK-NEXT: pmsltu.b a1, a1, a2
+; CHECK-NEXT: merge a1, a2, a3
+; CHECK-NEXT: sd a1, 0(a0)
+; CHECK-NEXT: ret
+ %a = load <8 x i8>, ptr %a_ptr
+ %b = load <8 x i8>, ptr %b_ptr
+ %c = load <8 x i8>, ptr %c_ptr
+ %mask = icmp ult <8 x i8> %a, %b
+ %res = select <8 x i1> %mask, <8 x i8> %c, <8 x i8> %b
+ store <8 x i8> %res, ptr %ret_ptr
+ ret void
+}
+
+define void @test_vselect_v2i32(ptr %ret_ptr, ptr %a_ptr, ptr %b_ptr, ptr %c_ptr) {
+; CHECK-LABEL: test_vselect_v2i32:
+; CHECK: # %bb.0:
+; CHECK-NEXT: ld a1, 0(a1)
+; CHECK-NEXT: ld a2, 0(a2)
+; CHECK-NEXT: ld a3, 0(a3)
+; CHECK-NEXT: pmslt.w a1, a2, a1
+; CHECK-NEXT: merge a1, a2, a3
+; CHECK-NEXT: sd a1, 0(a0)
+; CHECK-NEXT: ret
+ %a = load <2 x i32>, ptr %a_ptr
+ %b = load <2 x i32>, ptr %b_ptr
+ %c = load <2 x i32>, ptr %c_ptr
+ %mask = icmp sgt <2 x i32> %a, %b
+ %res = select <2 x i1> %mask, <2 x i32> %c, <2 x i32> %b
+ store <2 x i32> %res, ptr %ret_ptr
+ ret void
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/175744
More information about the llvm-commits
mailing list