[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