diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 838e2bbeb96fc..503b8ce521161 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -4478,6 +4478,17 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, IntNo == Intrinsic::riscv_grev ? RISCVISD::GREV : RISCVISD::GORC; return DAG.getNode(Opc, DL, XLenVT, Op.getOperand(1), Op.getOperand(2)); } + case Intrinsic::riscv_zip: + case Intrinsic::riscv_unzip: { + // Lower to the SHFLI encoding for zip or the UNSHFLI encoding for unzip. + // For i32 the immdiate is 15. For i64 the immediate is 31. + unsigned Opc = + IntNo == Intrinsic::riscv_zip ? RISCVISD::SHFL : RISCVISD::UNSHFL; + unsigned BitWidth = Op.getValueSizeInBits(); + assert(isPowerOf2_32(BitWidth) && BitWidth >= 2 && "Unexpected bit width"); + return DAG.getNode(Opc, DL, XLenVT, Op.getOperand(1), + DAG.getConstant((BitWidth / 2) - 1, DL, XLenVT)); + } case Intrinsic::riscv_shfl: case Intrinsic::riscv_unshfl: { unsigned Opc = diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td index 50849949bfb48..07884d35f63cd 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td @@ -855,6 +855,10 @@ let Predicates = [HasStdExtZbpOrZbkb] in { // We treat brev8 as a separate instruction, so match it directly. We also // use this for brev8 when lowering bitreverse with Zbkb. def : Pat<(riscv_grev GPR:$rs1, 7), (BREV8 GPR:$rs1)>; + +// We treat zip and unzip as separate instructions, so match it directly. +def : Pat<(i32 (riscv_shfl GPR:$rs1, 15)), (ZIP_RV32 GPR:$rs1)>; +def : Pat<(i32 (riscv_unshfl GPR:$rs1, 15)), (UNZIP_RV32 GPR:$rs1)>; } let Predicates = [HasStdExtZbp] in { @@ -897,10 +901,6 @@ def : Pat<(i32 (rotl (riscv_grev GPR:$rs1, 24), (i32 16))), (GREVI GPR:$rs1, 8)> // We treat rev8 as a separate instruction, so match it directly. def : Pat<(i32 (riscv_grev GPR:$rs1, 24)), (REV8_RV32 GPR:$rs1)>; - -// We treat zip and unzip as separate instructions, so match it directly. -def : Pat<(i32 (riscv_shfl GPR:$rs1, 15)), (ZIP_RV32 GPR:$rs1)>; -def : Pat<(i32 (riscv_unshfl GPR:$rs1, 15)), (UNZIP_RV32 GPR:$rs1)>; } // Predicates = [HasStdExtZbp, IsRV32] let Predicates = [HasStdExtZbp, IsRV64] in { @@ -1172,11 +1172,6 @@ def : PatGprGpr; let Predicates = [HasStdExtZbf, IsRV64] in def : PatGprGpr; -let Predicates = [HasStdExtZbkb, IsRV32] in { -def : PatGpr; -def : PatGpr; -} // Predicates = [HasStdExtZbkb, IsRV32] - let Predicates = [HasStdExtZbkx] in { def : PatGprGpr; def : PatGprGpr;