diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td @@ -1361,3 +1361,9 @@ def : Pat<(XVEI16VT (ctlz (rvp_vnot XVEI16VT:$rs1))), (CLO16 GPR:$rs1)>; def : Pat<(XVEI32VT (ctlz (rvp_vnot XVEI32VT:$rs1))), (CLO32 GPR:$rs1)>; } // Predicates = [HasStdExtZpn] + +// bpick +let Predicates = [HasStdExtZpn] in +def : Pat<(XLenVT (or (and GPR:$rs1, GPR:$rc), + (and GPR:$rs2, (not GPR:$rc)))), + (BPICK GPR:$rs1, GPR:$rs2, GPR:$rc)>; diff --git a/llvm/test/CodeGen/RISCV/rvp/bpick.ll b/llvm/test/CodeGen/RISCV/rvp/bpick.ll --- a/llvm/test/CodeGen/RISCV/rvp/bpick.ll +++ b/llvm/test/CodeGen/RISCV/rvp/bpick.ll @@ -7,18 +7,12 @@ define i32 @bpick32(i32 %a, i32 %b, i32 %mask) nounwind { ; RV32-LABEL: bpick32: ; RV32: # %bb.0: -; RV32-NEXT: and a0, a2, a0 -; RV32-NEXT: not a2, a2 -; RV32-NEXT: and a1, a2, a1 -; RV32-NEXT: or a0, a0, a1 +; RV32-NEXT: bpick a0, a0, a1, a2 ; RV32-NEXT: ret ; ; RV64-LABEL: bpick32: ; RV64: # %bb.0: -; RV64-NEXT: and a0, a2, a0 -; RV64-NEXT: not a2, a2 -; RV64-NEXT: and a1, a2, a1 -; RV64-NEXT: or a0, a0, a1 +; RV64-NEXT: bpick a0, a0, a1, a2 ; RV64-NEXT: ret %and1 = and i32 %mask, %a %neg = xor i32 %mask, -1 @@ -30,22 +24,13 @@ define i64 @bpick64(i64 %a, i64 %b, i64 %mask) nounwind { ; RV32-LABEL: bpick64: ; RV32: # %bb.0: -; RV32-NEXT: and a1, a5, a1 -; RV32-NEXT: and a0, a4, a0 -; RV32-NEXT: not a4, a4 -; RV32-NEXT: not a5, a5 -; RV32-NEXT: and a3, a5, a3 -; RV32-NEXT: and a2, a4, a2 -; RV32-NEXT: or a0, a0, a2 -; RV32-NEXT: or a1, a1, a3 +; RV32-NEXT: bpick a0, a0, a2, a4 +; RV32-NEXT: bpick a1, a1, a3, a5 ; RV32-NEXT: ret ; ; RV64-LABEL: bpick64: ; RV64: # %bb.0: -; RV64-NEXT: and a0, a2, a0 -; RV64-NEXT: not a2, a2 -; RV64-NEXT: and a1, a2, a1 -; RV64-NEXT: or a0, a0, a1 +; RV64-NEXT: bpick a0, a0, a1, a2 ; RV64-NEXT: ret %and1 = and i64 %mask, %a %neg = xor i64 %mask, -1