diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h --- a/llvm/lib/Target/RISCV/RISCVISelLowering.h +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -108,6 +108,11 @@ BCOMPRESSW, BDECOMPRESS, BDECOMPRESSW, + // Packed SIMD Extension + BSWAPH, + BSWAPW, + BSWAP, + BITREVI, // Vector Extension // VMV_V_X_VL matches the semantics of vmv.v.x but includes an extra operand // for the VL value to be used for the operation. diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -841,10 +841,20 @@ AddPromotedToType(ISD::STORE, VT, PromotedBitwiseVT); }; + setOperationAction(ISD::BITREVERSE, XLenVT, Custom); + setOperationAction(ISD::BSWAP, XLenVT, Custom); + setOperationAction(ISD::BITREVERSE, MVT::i8, Custom); + // BSWAP i8 doesn't exist. + setOperationAction(ISD::BITREVERSE, MVT::i16, Custom); + setOperationAction(ISD::BSWAP, MVT::i16, Custom); + if (Subtarget.is64Bit()) { addTypeForP(MVT::v8i8, MVT::i64); addTypeForP(MVT::v4i16, MVT::i64); addTypeForP(MVT::v2i32, MVT::i64); + + setOperationAction(ISD::BITREVERSE, MVT::i32, Custom); + setOperationAction(ISD::BSWAP, MVT::i32, Custom); } else { addTypeForP(MVT::v4i8, MVT::i32); addTypeForP(MVT::v2i16, MVT::i32); @@ -2091,15 +2101,21 @@ case ISD::BSWAP: case ISD::BITREVERSE: { // Convert BSWAP/BITREVERSE to GREVI to enable GREVI combinining. - assert(Subtarget.hasStdExtZbp() && "Unexpected custom legalisation"); + assert((Subtarget.hasStdExtZbp() || Subtarget.hasStdExtZpn()) && + "Unexpected custom legalisation"); MVT VT = Op.getSimpleValueType(); SDLoc DL(Op); + // Only RVP is enabled, lower BSWAP to customized BSWAP. + if (!Subtarget.hasStdExtZbp() && Op.getOpcode() == ISD::BSWAP) + return DAG.getNode(RISCVISD::BSWAP, DL, VT, Op.getOperand(0)); // Start with the maximum immediate value which is the bitwidth - 1. unsigned Imm = VT.getSizeInBits() - 1; // If this is BSWAP rather than BITREVERSE, clear the lower 3 bits. if (Op.getOpcode() == ISD::BSWAP) Imm &= ~0x7U; - return DAG.getNode(RISCVISD::GREV, DL, VT, Op.getOperand(0), + unsigned Opc = + Subtarget.hasStdExtZbp() ? RISCVISD::GREV : RISCVISD::BITREVI; + return DAG.getNode(Opc, DL, VT, Op.getOperand(0), DAG.getConstant(Imm, DL, VT)); } case ISD::FSHL: @@ -4992,18 +5008,29 @@ MVT XLenVT = Subtarget.getXLenVT(); assert((VT == MVT::i8 || VT == MVT::i16 || (VT == MVT::i32 && Subtarget.is64Bit())) && - Subtarget.hasStdExtZbp() && "Unexpected custom legalisation"); + (Subtarget.hasStdExtZbp() || Subtarget.hasStdExtZpn()) && + "Unexpected custom legalisation"); SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, DL, XLenVT, N->getOperand(0)); - unsigned Imm = VT.getSizeInBits() - 1; - // If this is BSWAP rather than BITREVERSE, clear the lower 3 bits. - if (N->getOpcode() == ISD::BSWAP) - Imm &= ~0x7U; - unsigned Opc = Subtarget.is64Bit() ? RISCVISD::GREVW : RISCVISD::GREV; - SDValue GREVI = - DAG.getNode(Opc, DL, XLenVT, NewOp0, DAG.getConstant(Imm, DL, XLenVT)); + SDValue NewOp; + // Only RVP is enabled, lower BSWAP to customized BSWAP. + if (!Subtarget.hasStdExtZbp() && N->getOpcode() == ISD::BSWAP) + NewOp = DAG.getNode(VT == MVT::i16 ? RISCVISD::BSWAPH : RISCVISD::BSWAPW, + DL, XLenVT, NewOp0); + else { + unsigned Imm = VT.getSizeInBits() - 1; + // If this is BSWAP rather than BITREVERSE, clear the lower 3 bits. + if (N->getOpcode() == ISD::BSWAP) + Imm &= ~0x7U; + unsigned Opc = + Subtarget.hasStdExtZbp() + ? Subtarget.is64Bit() ? RISCVISD::GREVW : RISCVISD::GREV + : RISCVISD::BITREVI; + NewOp = DAG.getNode(Opc, DL, XLenVT, NewOp0, + DAG.getConstant(Imm, DL, XLenVT)); + } // ReplaceNodeResults requires we maintain the same type for the return // value. - Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, VT, GREVI)); + Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, VT, NewOp)); break; } case ISD::FSHL: @@ -6293,6 +6320,14 @@ } break; } + case RISCVISD::BSWAPH: + Known.Zero.setBitsFrom(16); + break; + case RISCVISD::BITREVI: { + unsigned Imm = Op.getConstantOperandVal(1); + Known.Zero.setBitsFrom(Imm); + break; + } case RISCVISD::READ_VLENB: // We assume VLENB is at least 16 bytes. Known.Zero.setLowBits(4); @@ -8064,6 +8099,10 @@ NODE_NAME_CASE(BCOMPRESSW) NODE_NAME_CASE(BDECOMPRESS) NODE_NAME_CASE(BDECOMPRESSW) + NODE_NAME_CASE(BSWAPH) + NODE_NAME_CASE(BSWAPW) + NODE_NAME_CASE(BSWAP) + NODE_NAME_CASE(BITREVI) NODE_NAME_CASE(VMV_V_X_VL) NODE_NAME_CASE(VFMV_V_F_VL) NODE_NAME_CASE(VMV_X_S) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -34,6 +34,9 @@ SDTCisInt<2>]>; def SDT_RISCVReadCycleWide : SDTypeProfile<2, 0, [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; +def SDT_RISCVIntUnaryOp : SDTypeProfile<1, 1, [ + SDTCisSameAs<0, 1>, SDTCisVT<0, XLenVT> +]>; def SDT_RISCVIntUnaryOpW : SDTypeProfile<1, 1, [ SDTCisSameAs<0, 1>, SDTCisVT<0, i64> ]>; 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 @@ -17,6 +17,11 @@ // Operand and SDNode transformation definitions. //===----------------------------------------------------------------------===// +def riscv_bswaph : SDNode<"RISCVISD::BSWAPH", SDT_RISCVIntUnaryOp>; +def riscv_bswapw : SDNode<"RISCVISD::BSWAPW", SDT_RISCVIntUnaryOpW>; +def riscv_bswap : SDNode<"RISCVISD::BSWAP", SDT_RISCVIntUnaryOp>; +def riscv_bitrevi : SDNode<"RISCVISD::BITREVI", SDT_RISCVIntBinOp>; + def uimm3 : Operand, ImmLeaf(Imm);}]> { let ParserMatchClass = UImmAsmOperand<3>; let DecoderMethod = "decodeUImmOperand<3>"; @@ -1282,3 +1287,23 @@ def : PatALU32I; def : PatALU32I; } // [HasStdExtZpn, IsRV64] + +// bswap +let Predicates = [HasStdExtZpn] in +def : Pat<(riscv_bswaph GPR:$rs1), (SWAP8 GPR:$rs1)>; + +let Predicates = [HasStdExtZpn, IsRV32] in +def : Pat<(riscv_bswap i32:$rs1), (PKBT16 (SWAP8 GPR:$rs1), (SWAP8 GPR:$rs1))>; + +let Predicates = [HasStdExtZpn, IsRV64] in { +def : Pat<(riscv_bswapw GPR:$rs1), + (PKBT16 (SWAP8 GPR:$rs1), (SWAP8 GPR:$rs1))>; +def : Pat<(riscv_bswap i64:$rs1), + (PKBT32 (PKBT16 (SWAP8 GPR:$rs1), (SWAP8 GPR:$rs1)), + (PKBT16 (SWAP8 GPR:$rs1), (SWAP8 GPR:$rs1)))>; +} + +// bitreverse +let Predicates = [HasStdExtZpn] in +def : Pat<(riscv_bitrevi GPR:$rs1, uimmlog2xlen:$imm), + (BITREVI GPR:$rs1, uimmlog2xlen:$imm)>; diff --git a/llvm/test/CodeGen/RISCV/rv32zpn-bitreverse.ll b/llvm/test/CodeGen/RISCV/rv32zpn-bitreverse.ll --- a/llvm/test/CodeGen/RISCV/rv32zpn-bitreverse.ll +++ b/llvm/test/CodeGen/RISCV/rv32zpn-bitreverse.ll @@ -21,38 +21,12 @@ ; ; RV32IP-LABEL: bitreverse_i8: ; RV32IP: # %bb.0: -; RV32IP-NEXT: srli a1, a0, 4 -; RV32IP-NEXT: andi a0, a0, 15 -; RV32IP-NEXT: slli a0, a0, 4 -; RV32IP-NEXT: or a0, a1, a0 -; RV32IP-NEXT: andi a1, a0, 51 -; RV32IP-NEXT: slli a1, a1, 2 -; RV32IP-NEXT: andi a0, a0, 204 -; RV32IP-NEXT: srli a0, a0, 2 -; RV32IP-NEXT: or a0, a0, a1 -; RV32IP-NEXT: andi a1, a0, 85 -; RV32IP-NEXT: slli a1, a1, 1 -; RV32IP-NEXT: andi a0, a0, 170 -; RV32IP-NEXT: srli a0, a0, 1 -; RV32IP-NEXT: or a0, a0, a1 +; RV32IP-NEXT: bitrevi a0, a0, 7 ; RV32IP-NEXT: ret ; ; RV32IPN-LABEL: bitreverse_i8: ; RV32IPN: # %bb.0: -; RV32IPN-NEXT: srli a1, a0, 4 -; RV32IPN-NEXT: andi a0, a0, 15 -; RV32IPN-NEXT: slli a0, a0, 4 -; RV32IPN-NEXT: or a0, a1, a0 -; RV32IPN-NEXT: andi a1, a0, 51 -; RV32IPN-NEXT: slli a1, a1, 2 -; RV32IPN-NEXT: andi a0, a0, 204 -; RV32IPN-NEXT: srli a0, a0, 2 -; RV32IPN-NEXT: or a0, a0, a1 -; RV32IPN-NEXT: andi a1, a0, 85 -; RV32IPN-NEXT: slli a1, a1, 1 -; RV32IPN-NEXT: andi a0, a0, 170 -; RV32IPN-NEXT: srli a0, a0, 1 -; RV32IPN-NEXT: or a0, a0, a1 +; RV32IPN-NEXT: bitrevi a0, a0, 7 ; RV32IPN-NEXT: ret ; ; RV32IBP-LABEL: bitreverse_i8: @@ -71,70 +45,12 @@ ; ; RV32IP-LABEL: bitreverse_i16: ; RV32IP: # %bb.0: -; RV32IP-NEXT: srli a1, a0, 8 -; RV32IP-NEXT: slli a0, a0, 8 -; RV32IP-NEXT: or a0, a0, a1 -; RV32IP-NEXT: lui a1, 1 -; RV32IP-NEXT: addi a1, a1, -241 -; RV32IP-NEXT: and a1, a0, a1 -; RV32IP-NEXT: slli a1, a1, 4 -; RV32IP-NEXT: lui a2, 15 -; RV32IP-NEXT: addi a2, a2, 240 -; RV32IP-NEXT: and a0, a0, a2 -; RV32IP-NEXT: srli a0, a0, 4 -; RV32IP-NEXT: or a0, a0, a1 -; RV32IP-NEXT: lui a1, 3 -; RV32IP-NEXT: addi a1, a1, 819 -; RV32IP-NEXT: and a1, a0, a1 -; RV32IP-NEXT: slli a1, a1, 2 -; RV32IP-NEXT: lui a2, 13 -; RV32IP-NEXT: addi a2, a2, -820 -; RV32IP-NEXT: and a0, a0, a2 -; RV32IP-NEXT: srli a0, a0, 2 -; RV32IP-NEXT: or a0, a0, a1 -; RV32IP-NEXT: lui a1, 5 -; RV32IP-NEXT: addi a1, a1, 1365 -; RV32IP-NEXT: and a1, a0, a1 -; RV32IP-NEXT: slli a1, a1, 1 -; RV32IP-NEXT: lui a2, 11 -; RV32IP-NEXT: addi a2, a2, -1366 -; RV32IP-NEXT: and a0, a0, a2 -; RV32IP-NEXT: srli a0, a0, 1 -; RV32IP-NEXT: or a0, a0, a1 +; RV32IP-NEXT: bitrevi a0, a0, 15 ; RV32IP-NEXT: ret ; ; RV32IPN-LABEL: bitreverse_i16: ; RV32IPN: # %bb.0: -; RV32IPN-NEXT: srli a1, a0, 8 -; RV32IPN-NEXT: slli a0, a0, 8 -; RV32IPN-NEXT: or a0, a0, a1 -; RV32IPN-NEXT: lui a1, 1 -; RV32IPN-NEXT: addi a1, a1, -241 -; RV32IPN-NEXT: and a1, a0, a1 -; RV32IPN-NEXT: slli a1, a1, 4 -; RV32IPN-NEXT: lui a2, 15 -; RV32IPN-NEXT: addi a2, a2, 240 -; RV32IPN-NEXT: and a0, a0, a2 -; RV32IPN-NEXT: srli a0, a0, 4 -; RV32IPN-NEXT: or a0, a0, a1 -; RV32IPN-NEXT: lui a1, 3 -; RV32IPN-NEXT: addi a1, a1, 819 -; RV32IPN-NEXT: and a1, a0, a1 -; RV32IPN-NEXT: slli a1, a1, 2 -; RV32IPN-NEXT: lui a2, 13 -; RV32IPN-NEXT: addi a2, a2, -820 -; RV32IPN-NEXT: and a0, a0, a2 -; RV32IPN-NEXT: srli a0, a0, 2 -; RV32IPN-NEXT: or a0, a0, a1 -; RV32IPN-NEXT: lui a1, 5 -; RV32IPN-NEXT: addi a1, a1, 1365 -; RV32IPN-NEXT: and a1, a0, a1 -; RV32IPN-NEXT: slli a1, a1, 1 -; RV32IPN-NEXT: lui a2, 11 -; RV32IPN-NEXT: addi a2, a2, -1366 -; RV32IPN-NEXT: and a0, a0, a2 -; RV32IPN-NEXT: srli a0, a0, 1 -; RV32IPN-NEXT: or a0, a0, a1 +; RV32IPN-NEXT: bitrevi a0, a0, 15 ; RV32IPN-NEXT: ret ; ; RV32IBP-LABEL: bitreverse_i16: @@ -153,88 +69,12 @@ ; ; RV32IP-LABEL: bitreverse_i32: ; RV32IP: # %bb.0: -; RV32IP-NEXT: srli a1, a0, 8 -; RV32IP-NEXT: lui a2, 16 -; RV32IP-NEXT: addi a2, a2, -256 -; RV32IP-NEXT: and a1, a1, a2 -; RV32IP-NEXT: srli a2, a0, 24 -; RV32IP-NEXT: or a1, a1, a2 -; RV32IP-NEXT: slli a2, a0, 8 -; RV32IP-NEXT: lui a3, 4080 -; RV32IP-NEXT: and a2, a2, a3 -; RV32IP-NEXT: slli a0, a0, 24 -; RV32IP-NEXT: or a0, a0, a2 -; RV32IP-NEXT: or a0, a0, a1 -; RV32IP-NEXT: lui a1, 61681 -; RV32IP-NEXT: addi a1, a1, -241 -; RV32IP-NEXT: and a1, a0, a1 -; RV32IP-NEXT: slli a1, a1, 4 -; RV32IP-NEXT: lui a2, 986895 -; RV32IP-NEXT: addi a2, a2, 240 -; RV32IP-NEXT: and a0, a0, a2 -; RV32IP-NEXT: srli a0, a0, 4 -; RV32IP-NEXT: or a0, a0, a1 -; RV32IP-NEXT: lui a1, 209715 -; RV32IP-NEXT: addi a1, a1, 819 -; RV32IP-NEXT: and a1, a0, a1 -; RV32IP-NEXT: slli a1, a1, 2 -; RV32IP-NEXT: lui a2, 838861 -; RV32IP-NEXT: addi a2, a2, -820 -; RV32IP-NEXT: and a0, a0, a2 -; RV32IP-NEXT: srli a0, a0, 2 -; RV32IP-NEXT: or a0, a0, a1 -; RV32IP-NEXT: lui a1, 349525 -; RV32IP-NEXT: addi a1, a1, 1365 -; RV32IP-NEXT: and a1, a0, a1 -; RV32IP-NEXT: slli a1, a1, 1 -; RV32IP-NEXT: lui a2, 699051 -; RV32IP-NEXT: addi a2, a2, -1366 -; RV32IP-NEXT: and a0, a0, a2 -; RV32IP-NEXT: srli a0, a0, 1 -; RV32IP-NEXT: or a0, a0, a1 +; RV32IP-NEXT: bitrevi a0, a0, 31 ; RV32IP-NEXT: ret ; ; RV32IPN-LABEL: bitreverse_i32: ; RV32IPN: # %bb.0: -; RV32IPN-NEXT: srli a1, a0, 8 -; RV32IPN-NEXT: lui a2, 16 -; RV32IPN-NEXT: addi a2, a2, -256 -; RV32IPN-NEXT: and a1, a1, a2 -; RV32IPN-NEXT: srli a2, a0, 24 -; RV32IPN-NEXT: or a1, a1, a2 -; RV32IPN-NEXT: slli a2, a0, 8 -; RV32IPN-NEXT: lui a3, 4080 -; RV32IPN-NEXT: and a2, a2, a3 -; RV32IPN-NEXT: slli a0, a0, 24 -; RV32IPN-NEXT: or a0, a0, a2 -; RV32IPN-NEXT: or a0, a0, a1 -; RV32IPN-NEXT: lui a1, 61681 -; RV32IPN-NEXT: addi a1, a1, -241 -; RV32IPN-NEXT: and a1, a0, a1 -; RV32IPN-NEXT: slli a1, a1, 4 -; RV32IPN-NEXT: lui a2, 986895 -; RV32IPN-NEXT: addi a2, a2, 240 -; RV32IPN-NEXT: and a0, a0, a2 -; RV32IPN-NEXT: srli a0, a0, 4 -; RV32IPN-NEXT: or a0, a0, a1 -; RV32IPN-NEXT: lui a1, 209715 -; RV32IPN-NEXT: addi a1, a1, 819 -; RV32IPN-NEXT: and a1, a0, a1 -; RV32IPN-NEXT: slli a1, a1, 2 -; RV32IPN-NEXT: lui a2, 838861 -; RV32IPN-NEXT: addi a2, a2, -820 -; RV32IPN-NEXT: and a0, a0, a2 -; RV32IPN-NEXT: srli a0, a0, 2 -; RV32IPN-NEXT: or a0, a0, a1 -; RV32IPN-NEXT: lui a1, 349525 -; RV32IPN-NEXT: addi a1, a1, 1365 -; RV32IPN-NEXT: and a1, a0, a1 -; RV32IPN-NEXT: slli a1, a1, 1 -; RV32IPN-NEXT: lui a2, 699051 -; RV32IPN-NEXT: addi a2, a2, -1366 -; RV32IPN-NEXT: and a0, a0, a2 -; RV32IPN-NEXT: srli a0, a0, 1 -; RV32IPN-NEXT: or a0, a0, a1 +; RV32IPN-NEXT: bitrevi a0, a0, 31 ; RV32IPN-NEXT: ret ; ; RV32IBP-LABEL: bitreverse_i32: @@ -255,138 +95,16 @@ ; ; RV32IP-LABEL: bitreverse_i64: ; RV32IP: # %bb.0: -; RV32IP-NEXT: srli a2, a1, 8 -; RV32IP-NEXT: lui a3, 16 -; RV32IP-NEXT: addi t0, a3, -256 -; RV32IP-NEXT: and a2, a2, t0 -; RV32IP-NEXT: srli a4, a1, 24 -; RV32IP-NEXT: or a2, a2, a4 -; RV32IP-NEXT: slli a4, a1, 8 -; RV32IP-NEXT: lui a6, 4080 -; RV32IP-NEXT: and a4, a4, a6 -; RV32IP-NEXT: slli a1, a1, 24 -; RV32IP-NEXT: or a1, a1, a4 -; RV32IP-NEXT: or a1, a1, a2 -; RV32IP-NEXT: lui a2, 61681 -; RV32IP-NEXT: addi t1, a2, -241 -; RV32IP-NEXT: and a2, a1, t1 -; RV32IP-NEXT: slli a2, a2, 4 -; RV32IP-NEXT: lui a5, 986895 -; RV32IP-NEXT: addi t2, a5, 240 -; RV32IP-NEXT: and a1, a1, t2 -; RV32IP-NEXT: srli a1, a1, 4 -; RV32IP-NEXT: or a1, a1, a2 -; RV32IP-NEXT: lui a2, 209715 -; RV32IP-NEXT: addi t3, a2, 819 -; RV32IP-NEXT: and a3, a1, t3 -; RV32IP-NEXT: slli a3, a3, 2 -; RV32IP-NEXT: lui a4, 838861 -; RV32IP-NEXT: addi a4, a4, -820 -; RV32IP-NEXT: and a1, a1, a4 -; RV32IP-NEXT: srli a1, a1, 2 -; RV32IP-NEXT: or a1, a1, a3 -; RV32IP-NEXT: lui a3, 349525 -; RV32IP-NEXT: addi a3, a3, 1365 -; RV32IP-NEXT: and a5, a1, a3 -; RV32IP-NEXT: slli a5, a5, 1 -; RV32IP-NEXT: lui a2, 699051 -; RV32IP-NEXT: addi a2, a2, -1366 -; RV32IP-NEXT: and a1, a1, a2 -; RV32IP-NEXT: srli a1, a1, 1 -; RV32IP-NEXT: or a7, a1, a5 -; RV32IP-NEXT: srli a1, a0, 8 -; RV32IP-NEXT: and a1, a1, t0 -; RV32IP-NEXT: srli a5, a0, 24 -; RV32IP-NEXT: or a1, a1, a5 -; RV32IP-NEXT: slli a5, a0, 8 -; RV32IP-NEXT: and a5, a5, a6 -; RV32IP-NEXT: slli a0, a0, 24 -; RV32IP-NEXT: or a0, a0, a5 -; RV32IP-NEXT: or a0, a0, a1 -; RV32IP-NEXT: and a1, a0, t1 -; RV32IP-NEXT: slli a1, a1, 4 -; RV32IP-NEXT: and a0, a0, t2 -; RV32IP-NEXT: srli a0, a0, 4 -; RV32IP-NEXT: or a0, a0, a1 -; RV32IP-NEXT: and a1, a0, t3 -; RV32IP-NEXT: slli a1, a1, 2 -; RV32IP-NEXT: and a0, a0, a4 -; RV32IP-NEXT: srli a0, a0, 2 -; RV32IP-NEXT: or a0, a0, a1 -; RV32IP-NEXT: and a1, a0, a3 -; RV32IP-NEXT: slli a1, a1, 1 -; RV32IP-NEXT: and a0, a0, a2 -; RV32IP-NEXT: srli a0, a0, 1 -; RV32IP-NEXT: or a1, a0, a1 -; RV32IP-NEXT: mv a0, a7 +; RV32IP-NEXT: bitrevi a2, a1, 31 +; RV32IP-NEXT: bitrevi a1, a0, 31 +; RV32IP-NEXT: mv a0, a2 ; RV32IP-NEXT: ret ; ; RV32IPN-LABEL: bitreverse_i64: ; RV32IPN: # %bb.0: -; RV32IPN-NEXT: srli a2, a1, 8 -; RV32IPN-NEXT: lui a3, 16 -; RV32IPN-NEXT: addi t0, a3, -256 -; RV32IPN-NEXT: and a2, a2, t0 -; RV32IPN-NEXT: srli a4, a1, 24 -; RV32IPN-NEXT: or a2, a2, a4 -; RV32IPN-NEXT: slli a4, a1, 8 -; RV32IPN-NEXT: lui a6, 4080 -; RV32IPN-NEXT: and a4, a4, a6 -; RV32IPN-NEXT: slli a1, a1, 24 -; RV32IPN-NEXT: or a1, a1, a4 -; RV32IPN-NEXT: or a1, a1, a2 -; RV32IPN-NEXT: lui a2, 61681 -; RV32IPN-NEXT: addi t1, a2, -241 -; RV32IPN-NEXT: and a2, a1, t1 -; RV32IPN-NEXT: slli a2, a2, 4 -; RV32IPN-NEXT: lui a5, 986895 -; RV32IPN-NEXT: addi t2, a5, 240 -; RV32IPN-NEXT: and a1, a1, t2 -; RV32IPN-NEXT: srli a1, a1, 4 -; RV32IPN-NEXT: or a1, a1, a2 -; RV32IPN-NEXT: lui a2, 209715 -; RV32IPN-NEXT: addi t3, a2, 819 -; RV32IPN-NEXT: and a3, a1, t3 -; RV32IPN-NEXT: slli a3, a3, 2 -; RV32IPN-NEXT: lui a4, 838861 -; RV32IPN-NEXT: addi a4, a4, -820 -; RV32IPN-NEXT: and a1, a1, a4 -; RV32IPN-NEXT: srli a1, a1, 2 -; RV32IPN-NEXT: or a1, a1, a3 -; RV32IPN-NEXT: lui a3, 349525 -; RV32IPN-NEXT: addi a3, a3, 1365 -; RV32IPN-NEXT: and a5, a1, a3 -; RV32IPN-NEXT: slli a5, a5, 1 -; RV32IPN-NEXT: lui a2, 699051 -; RV32IPN-NEXT: addi a2, a2, -1366 -; RV32IPN-NEXT: and a1, a1, a2 -; RV32IPN-NEXT: srli a1, a1, 1 -; RV32IPN-NEXT: or a7, a1, a5 -; RV32IPN-NEXT: srli a1, a0, 8 -; RV32IPN-NEXT: and a1, a1, t0 -; RV32IPN-NEXT: srli a5, a0, 24 -; RV32IPN-NEXT: or a1, a1, a5 -; RV32IPN-NEXT: slli a5, a0, 8 -; RV32IPN-NEXT: and a5, a5, a6 -; RV32IPN-NEXT: slli a0, a0, 24 -; RV32IPN-NEXT: or a0, a0, a5 -; RV32IPN-NEXT: or a0, a0, a1 -; RV32IPN-NEXT: and a1, a0, t1 -; RV32IPN-NEXT: slli a1, a1, 4 -; RV32IPN-NEXT: and a0, a0, t2 -; RV32IPN-NEXT: srli a0, a0, 4 -; RV32IPN-NEXT: or a0, a0, a1 -; RV32IPN-NEXT: and a1, a0, t3 -; RV32IPN-NEXT: slli a1, a1, 2 -; RV32IPN-NEXT: and a0, a0, a4 -; RV32IPN-NEXT: srli a0, a0, 2 -; RV32IPN-NEXT: or a0, a0, a1 -; RV32IPN-NEXT: and a1, a0, a3 -; RV32IPN-NEXT: slli a1, a1, 1 -; RV32IPN-NEXT: and a0, a0, a2 -; RV32IPN-NEXT: srli a0, a0, 1 -; RV32IPN-NEXT: or a1, a0, a1 -; RV32IPN-NEXT: mv a0, a7 +; RV32IPN-NEXT: bitrevi a2, a1, 31 +; RV32IPN-NEXT: bitrevi a1, a0, 31 +; RV32IPN-NEXT: mv a0, a2 ; RV32IPN-NEXT: ret ; ; RV32IBP-LABEL: bitreverse_i64: diff --git a/llvm/test/CodeGen/RISCV/rv32zpn-bswap.ll b/llvm/test/CodeGen/RISCV/rv32zpn-bswap.ll --- a/llvm/test/CodeGen/RISCV/rv32zpn-bswap.ll +++ b/llvm/test/CodeGen/RISCV/rv32zpn-bswap.ll @@ -20,22 +20,12 @@ ; ; RV32IP-LABEL: bswap_i16: ; RV32IP: # %bb.0: -; RV32IP-NEXT: srli a1, a0, 8 -; RV32IP-NEXT: slli a0, a0, 8 -; RV32IP-NEXT: or a0, a0, a1 -; RV32IP-NEXT: lui a1, 16 -; RV32IP-NEXT: addi a1, a1, -1 -; RV32IP-NEXT: and a0, a0, a1 +; RV32IP-NEXT: swap8 a0, a0 ; RV32IP-NEXT: ret ; ; RV32IPN-LABEL: bswap_i16: ; RV32IPN: # %bb.0: -; RV32IPN-NEXT: srli a1, a0, 8 -; RV32IPN-NEXT: slli a0, a0, 8 -; RV32IPN-NEXT: or a0, a0, a1 -; RV32IPN-NEXT: lui a1, 16 -; RV32IPN-NEXT: addi a1, a1, -1 -; RV32IPN-NEXT: and a0, a0, a1 +; RV32IPN-NEXT: swap8 a0, a0 ; RV32IPN-NEXT: ret ; ; RV32IBP-LABEL: bswap_i16: @@ -54,34 +44,14 @@ ; ; RV32IP-LABEL: bswap_i32: ; RV32IP: # %bb.0: -; RV32IP-NEXT: srli a1, a0, 8 -; RV32IP-NEXT: lui a2, 16 -; RV32IP-NEXT: addi a2, a2, -256 -; RV32IP-NEXT: and a1, a1, a2 -; RV32IP-NEXT: srli a2, a0, 24 -; RV32IP-NEXT: or a1, a1, a2 -; RV32IP-NEXT: slli a2, a0, 8 -; RV32IP-NEXT: lui a3, 4080 -; RV32IP-NEXT: and a2, a2, a3 -; RV32IP-NEXT: slli a0, a0, 24 -; RV32IP-NEXT: or a0, a0, a2 -; RV32IP-NEXT: or a0, a0, a1 +; RV32IP-NEXT: swap8 a0, a0 +; RV32IP-NEXT: swap16 a0, a0 ; RV32IP-NEXT: ret ; ; RV32IPN-LABEL: bswap_i32: ; RV32IPN: # %bb.0: -; RV32IPN-NEXT: srli a1, a0, 8 -; RV32IPN-NEXT: lui a2, 16 -; RV32IPN-NEXT: addi a2, a2, -256 -; RV32IPN-NEXT: and a1, a1, a2 -; RV32IPN-NEXT: srli a2, a0, 24 -; RV32IPN-NEXT: or a1, a1, a2 -; RV32IPN-NEXT: slli a2, a0, 8 -; RV32IPN-NEXT: lui a3, 4080 -; RV32IPN-NEXT: and a2, a2, a3 -; RV32IPN-NEXT: slli a0, a0, 24 -; RV32IPN-NEXT: or a0, a0, a2 -; RV32IPN-NEXT: or a0, a0, a1 +; RV32IPN-NEXT: swap8 a0, a0 +; RV32IPN-NEXT: swap16 a0, a0 ; RV32IPN-NEXT: ret ; ; RV32IBP-LABEL: bswap_i32: @@ -102,53 +72,19 @@ ; ; RV32IP-LABEL: bswap_i64: ; RV32IP: # %bb.0: -; RV32IP-NEXT: srli a2, a1, 8 -; RV32IP-NEXT: lui a3, 16 -; RV32IP-NEXT: addi a3, a3, -256 -; RV32IP-NEXT: and a2, a2, a3 -; RV32IP-NEXT: srli a4, a1, 24 -; RV32IP-NEXT: or a2, a2, a4 -; RV32IP-NEXT: slli a4, a1, 8 -; RV32IP-NEXT: lui a5, 4080 -; RV32IP-NEXT: and a4, a4, a5 -; RV32IP-NEXT: slli a1, a1, 24 -; RV32IP-NEXT: or a1, a1, a4 -; RV32IP-NEXT: or a2, a1, a2 -; RV32IP-NEXT: srli a1, a0, 8 -; RV32IP-NEXT: and a1, a1, a3 -; RV32IP-NEXT: srli a3, a0, 24 -; RV32IP-NEXT: or a1, a1, a3 -; RV32IP-NEXT: slli a3, a0, 8 -; RV32IP-NEXT: and a3, a3, a5 -; RV32IP-NEXT: slli a0, a0, 24 -; RV32IP-NEXT: or a0, a0, a3 -; RV32IP-NEXT: or a1, a0, a1 +; RV32IP-NEXT: swap8 a1, a1 +; RV32IP-NEXT: swap16 a2, a1 +; RV32IP-NEXT: swap8 a0, a0 +; RV32IP-NEXT: swap16 a1, a0 ; RV32IP-NEXT: mv a0, a2 ; RV32IP-NEXT: ret ; ; RV32IPN-LABEL: bswap_i64: ; RV32IPN: # %bb.0: -; RV32IPN-NEXT: srli a2, a1, 8 -; RV32IPN-NEXT: lui a3, 16 -; RV32IPN-NEXT: addi a3, a3, -256 -; RV32IPN-NEXT: and a2, a2, a3 -; RV32IPN-NEXT: srli a4, a1, 24 -; RV32IPN-NEXT: or a2, a2, a4 -; RV32IPN-NEXT: slli a4, a1, 8 -; RV32IPN-NEXT: lui a5, 4080 -; RV32IPN-NEXT: and a4, a4, a5 -; RV32IPN-NEXT: slli a1, a1, 24 -; RV32IPN-NEXT: or a1, a1, a4 -; RV32IPN-NEXT: or a2, a1, a2 -; RV32IPN-NEXT: srli a1, a0, 8 -; RV32IPN-NEXT: and a1, a1, a3 -; RV32IPN-NEXT: srli a3, a0, 24 -; RV32IPN-NEXT: or a1, a1, a3 -; RV32IPN-NEXT: slli a3, a0, 8 -; RV32IPN-NEXT: and a3, a3, a5 -; RV32IPN-NEXT: slli a0, a0, 24 -; RV32IPN-NEXT: or a0, a0, a3 -; RV32IPN-NEXT: or a1, a0, a1 +; RV32IPN-NEXT: swap8 a1, a1 +; RV32IPN-NEXT: swap16 a2, a1 +; RV32IPN-NEXT: swap8 a0, a0 +; RV32IPN-NEXT: swap16 a1, a0 ; RV32IPN-NEXT: mv a0, a2 ; RV32IPN-NEXT: ret ; diff --git a/llvm/test/CodeGen/RISCV/rv64zpn-bitreverse.ll b/llvm/test/CodeGen/RISCV/rv64zpn-bitreverse.ll --- a/llvm/test/CodeGen/RISCV/rv64zpn-bitreverse.ll +++ b/llvm/test/CodeGen/RISCV/rv64zpn-bitreverse.ll @@ -21,38 +21,12 @@ ; ; RV64IP-LABEL: bitreverse_i8: ; RV64IP: # %bb.0: -; RV64IP-NEXT: srli a1, a0, 4 -; RV64IP-NEXT: andi a0, a0, 15 -; RV64IP-NEXT: slli a0, a0, 4 -; RV64IP-NEXT: or a0, a1, a0 -; RV64IP-NEXT: andi a1, a0, 51 -; RV64IP-NEXT: slli a1, a1, 2 -; RV64IP-NEXT: andi a0, a0, 204 -; RV64IP-NEXT: srli a0, a0, 2 -; RV64IP-NEXT: or a0, a0, a1 -; RV64IP-NEXT: andi a1, a0, 85 -; RV64IP-NEXT: slli a1, a1, 1 -; RV64IP-NEXT: andi a0, a0, 170 -; RV64IP-NEXT: srli a0, a0, 1 -; RV64IP-NEXT: or a0, a0, a1 +; RV64IP-NEXT: bitrevi a0, a0, 7 ; RV64IP-NEXT: ret ; ; RV64IPN-LABEL: bitreverse_i8: ; RV64IPN: # %bb.0: -; RV64IPN-NEXT: srli a1, a0, 4 -; RV64IPN-NEXT: andi a0, a0, 15 -; RV64IPN-NEXT: slli a0, a0, 4 -; RV64IPN-NEXT: or a0, a1, a0 -; RV64IPN-NEXT: andi a1, a0, 51 -; RV64IPN-NEXT: slli a1, a1, 2 -; RV64IPN-NEXT: andi a0, a0, 204 -; RV64IPN-NEXT: srli a0, a0, 2 -; RV64IPN-NEXT: or a0, a0, a1 -; RV64IPN-NEXT: andi a1, a0, 85 -; RV64IPN-NEXT: slli a1, a1, 1 -; RV64IPN-NEXT: andi a0, a0, 170 -; RV64IPN-NEXT: srli a0, a0, 1 -; RV64IPN-NEXT: or a0, a0, a1 +; RV64IPN-NEXT: bitrevi a0, a0, 7 ; RV64IPN-NEXT: ret ; ; RV64IBP-LABEL: bitreverse_i8: @@ -71,70 +45,12 @@ ; ; RV64IP-LABEL: bitreverse_i16: ; RV64IP: # %bb.0: -; RV64IP-NEXT: srli a1, a0, 8 -; RV64IP-NEXT: slli a0, a0, 8 -; RV64IP-NEXT: or a0, a0, a1 -; RV64IP-NEXT: lui a1, 1 -; RV64IP-NEXT: addiw a1, a1, -241 -; RV64IP-NEXT: and a1, a0, a1 -; RV64IP-NEXT: slli a1, a1, 4 -; RV64IP-NEXT: lui a2, 15 -; RV64IP-NEXT: addiw a2, a2, 240 -; RV64IP-NEXT: and a0, a0, a2 -; RV64IP-NEXT: srli a0, a0, 4 -; RV64IP-NEXT: or a0, a0, a1 -; RV64IP-NEXT: lui a1, 3 -; RV64IP-NEXT: addiw a1, a1, 819 -; RV64IP-NEXT: and a1, a0, a1 -; RV64IP-NEXT: slli a1, a1, 2 -; RV64IP-NEXT: lui a2, 13 -; RV64IP-NEXT: addiw a2, a2, -820 -; RV64IP-NEXT: and a0, a0, a2 -; RV64IP-NEXT: srli a0, a0, 2 -; RV64IP-NEXT: or a0, a0, a1 -; RV64IP-NEXT: lui a1, 5 -; RV64IP-NEXT: addiw a1, a1, 1365 -; RV64IP-NEXT: and a1, a0, a1 -; RV64IP-NEXT: slli a1, a1, 1 -; RV64IP-NEXT: lui a2, 11 -; RV64IP-NEXT: addiw a2, a2, -1366 -; RV64IP-NEXT: and a0, a0, a2 -; RV64IP-NEXT: srli a0, a0, 1 -; RV64IP-NEXT: or a0, a0, a1 +; RV64IP-NEXT: bitrevi a0, a0, 15 ; RV64IP-NEXT: ret ; ; RV64IPN-LABEL: bitreverse_i16: ; RV64IPN: # %bb.0: -; RV64IPN-NEXT: srli a1, a0, 8 -; RV64IPN-NEXT: slli a0, a0, 8 -; RV64IPN-NEXT: or a0, a0, a1 -; RV64IPN-NEXT: lui a1, 1 -; RV64IPN-NEXT: addiw a1, a1, -241 -; RV64IPN-NEXT: and a1, a0, a1 -; RV64IPN-NEXT: slli a1, a1, 4 -; RV64IPN-NEXT: lui a2, 15 -; RV64IPN-NEXT: addiw a2, a2, 240 -; RV64IPN-NEXT: and a0, a0, a2 -; RV64IPN-NEXT: srli a0, a0, 4 -; RV64IPN-NEXT: or a0, a0, a1 -; RV64IPN-NEXT: lui a1, 3 -; RV64IPN-NEXT: addiw a1, a1, 819 -; RV64IPN-NEXT: and a1, a0, a1 -; RV64IPN-NEXT: slli a1, a1, 2 -; RV64IPN-NEXT: lui a2, 13 -; RV64IPN-NEXT: addiw a2, a2, -820 -; RV64IPN-NEXT: and a0, a0, a2 -; RV64IPN-NEXT: srli a0, a0, 2 -; RV64IPN-NEXT: or a0, a0, a1 -; RV64IPN-NEXT: lui a1, 5 -; RV64IPN-NEXT: addiw a1, a1, 1365 -; RV64IPN-NEXT: and a1, a0, a1 -; RV64IPN-NEXT: slli a1, a1, 1 -; RV64IPN-NEXT: lui a2, 11 -; RV64IPN-NEXT: addiw a2, a2, -1366 -; RV64IPN-NEXT: and a0, a0, a2 -; RV64IPN-NEXT: srli a0, a0, 1 -; RV64IPN-NEXT: or a0, a0, a1 +; RV64IPN-NEXT: bitrevi a0, a0, 15 ; RV64IPN-NEXT: ret ; ; RV64IBP-LABEL: bitreverse_i16: @@ -153,94 +69,12 @@ ; ; RV64IP-LABEL: bitreverse_i32: ; RV64IP: # %bb.0: -; RV64IP-NEXT: srliw a1, a0, 8 -; RV64IP-NEXT: lui a2, 16 -; RV64IP-NEXT: addiw a2, a2, -256 -; RV64IP-NEXT: and a1, a1, a2 -; RV64IP-NEXT: srliw a2, a0, 24 -; RV64IP-NEXT: or a1, a1, a2 -; RV64IP-NEXT: slli a2, a0, 8 -; RV64IP-NEXT: lui a3, 4080 -; RV64IP-NEXT: and a2, a2, a3 -; RV64IP-NEXT: slli a0, a0, 24 -; RV64IP-NEXT: or a0, a0, a2 -; RV64IP-NEXT: or a0, a0, a1 -; RV64IP-NEXT: lui a1, 61681 -; RV64IP-NEXT: addiw a1, a1, -241 -; RV64IP-NEXT: and a1, a0, a1 -; RV64IP-NEXT: slli a1, a1, 4 -; RV64IP-NEXT: lui a2, 241 -; RV64IP-NEXT: addiw a2, a2, -241 -; RV64IP-NEXT: slli a2, a2, 12 -; RV64IP-NEXT: addi a2, a2, 240 -; RV64IP-NEXT: and a0, a0, a2 -; RV64IP-NEXT: srli a0, a0, 4 -; RV64IP-NEXT: or a0, a0, a1 -; RV64IP-NEXT: lui a1, 209715 -; RV64IP-NEXT: addiw a1, a1, 819 -; RV64IP-NEXT: and a1, a0, a1 -; RV64IP-NEXT: slli a1, a1, 2 -; RV64IP-NEXT: lui a2, 838861 -; RV64IP-NEXT: addiw a2, a2, -820 -; RV64IP-NEXT: and a0, a0, a2 -; RV64IP-NEXT: srli a0, a0, 2 -; RV64IP-NEXT: or a0, a0, a1 -; RV64IP-NEXT: lui a1, 349525 -; RV64IP-NEXT: addiw a1, a1, 1365 -; RV64IP-NEXT: and a1, a0, a1 -; RV64IP-NEXT: slli a1, a1, 1 -; RV64IP-NEXT: lui a2, 699051 -; RV64IP-NEXT: addiw a2, a2, -1366 -; RV64IP-NEXT: and a0, a0, a2 -; RV64IP-NEXT: srli a0, a0, 1 -; RV64IP-NEXT: or a0, a0, a1 -; RV64IP-NEXT: sext.w a0, a0 +; RV64IP-NEXT: bitrevi a0, a0, 31 ; RV64IP-NEXT: ret ; ; RV64IPN-LABEL: bitreverse_i32: ; RV64IPN: # %bb.0: -; RV64IPN-NEXT: srliw a1, a0, 8 -; RV64IPN-NEXT: lui a2, 16 -; RV64IPN-NEXT: addiw a2, a2, -256 -; RV64IPN-NEXT: and a1, a1, a2 -; RV64IPN-NEXT: srliw a2, a0, 24 -; RV64IPN-NEXT: or a1, a1, a2 -; RV64IPN-NEXT: slli a2, a0, 8 -; RV64IPN-NEXT: lui a3, 4080 -; RV64IPN-NEXT: and a2, a2, a3 -; RV64IPN-NEXT: slli a0, a0, 24 -; RV64IPN-NEXT: or a0, a0, a2 -; RV64IPN-NEXT: or a0, a0, a1 -; RV64IPN-NEXT: lui a1, 61681 -; RV64IPN-NEXT: addiw a1, a1, -241 -; RV64IPN-NEXT: and a1, a0, a1 -; RV64IPN-NEXT: slli a1, a1, 4 -; RV64IPN-NEXT: lui a2, 241 -; RV64IPN-NEXT: addiw a2, a2, -241 -; RV64IPN-NEXT: slli a2, a2, 12 -; RV64IPN-NEXT: addi a2, a2, 240 -; RV64IPN-NEXT: and a0, a0, a2 -; RV64IPN-NEXT: srli a0, a0, 4 -; RV64IPN-NEXT: or a0, a0, a1 -; RV64IPN-NEXT: lui a1, 209715 -; RV64IPN-NEXT: addiw a1, a1, 819 -; RV64IPN-NEXT: and a1, a0, a1 -; RV64IPN-NEXT: slli a1, a1, 2 -; RV64IPN-NEXT: lui a2, 838861 -; RV64IPN-NEXT: addiw a2, a2, -820 -; RV64IPN-NEXT: and a0, a0, a2 -; RV64IPN-NEXT: srli a0, a0, 2 -; RV64IPN-NEXT: or a0, a0, a1 -; RV64IPN-NEXT: lui a1, 349525 -; RV64IPN-NEXT: addiw a1, a1, 1365 -; RV64IPN-NEXT: and a1, a0, a1 -; RV64IPN-NEXT: slli a1, a1, 1 -; RV64IPN-NEXT: lui a2, 699051 -; RV64IPN-NEXT: addiw a2, a2, -1366 -; RV64IPN-NEXT: and a0, a0, a2 -; RV64IPN-NEXT: srli a0, a0, 1 -; RV64IPN-NEXT: or a0, a0, a1 -; RV64IPN-NEXT: sext.w a0, a0 +; RV64IPN-NEXT: bitrevi a0, a0, 31 ; RV64IPN-NEXT: ret ; ; RV64IBP-LABEL: bitreverse_i32: @@ -261,93 +95,13 @@ ; ; RV64IP-LABEL: bitreverse_i32_nosext: ; RV64IP: # %bb.0: -; RV64IP-NEXT: srliw a2, a0, 8 -; RV64IP-NEXT: lui a3, 16 -; RV64IP-NEXT: addiw a3, a3, -256 -; RV64IP-NEXT: and a2, a2, a3 -; RV64IP-NEXT: srliw a3, a0, 24 -; RV64IP-NEXT: or a2, a2, a3 -; RV64IP-NEXT: slli a3, a0, 8 -; RV64IP-NEXT: lui a4, 4080 -; RV64IP-NEXT: and a3, a3, a4 -; RV64IP-NEXT: slli a0, a0, 24 -; RV64IP-NEXT: or a0, a0, a3 -; RV64IP-NEXT: or a0, a0, a2 -; RV64IP-NEXT: lui a2, 61681 -; RV64IP-NEXT: addiw a2, a2, -241 -; RV64IP-NEXT: and a2, a0, a2 -; RV64IP-NEXT: slli a2, a2, 4 -; RV64IP-NEXT: lui a3, 241 -; RV64IP-NEXT: addiw a3, a3, -241 -; RV64IP-NEXT: slli a3, a3, 12 -; RV64IP-NEXT: addi a3, a3, 240 -; RV64IP-NEXT: and a0, a0, a3 -; RV64IP-NEXT: srli a0, a0, 4 -; RV64IP-NEXT: or a0, a0, a2 -; RV64IP-NEXT: lui a2, 209715 -; RV64IP-NEXT: addiw a2, a2, 819 -; RV64IP-NEXT: and a2, a0, a2 -; RV64IP-NEXT: slli a2, a2, 2 -; RV64IP-NEXT: lui a3, 838861 -; RV64IP-NEXT: addiw a3, a3, -820 -; RV64IP-NEXT: and a0, a0, a3 -; RV64IP-NEXT: srli a0, a0, 2 -; RV64IP-NEXT: or a0, a0, a2 -; RV64IP-NEXT: lui a2, 349525 -; RV64IP-NEXT: addiw a2, a2, 1365 -; RV64IP-NEXT: and a2, a0, a2 -; RV64IP-NEXT: slli a2, a2, 1 -; RV64IP-NEXT: lui a3, 699051 -; RV64IP-NEXT: addiw a3, a3, -1366 -; RV64IP-NEXT: and a0, a0, a3 -; RV64IP-NEXT: srli a0, a0, 1 -; RV64IP-NEXT: or a0, a0, a2 +; RV64IP-NEXT: bitrevi a0, a0, 31 ; RV64IP-NEXT: sw a0, 0(a1) ; RV64IP-NEXT: ret ; ; RV64IPN-LABEL: bitreverse_i32_nosext: ; RV64IPN: # %bb.0: -; RV64IPN-NEXT: srliw a2, a0, 8 -; RV64IPN-NEXT: lui a3, 16 -; RV64IPN-NEXT: addiw a3, a3, -256 -; RV64IPN-NEXT: and a2, a2, a3 -; RV64IPN-NEXT: srliw a3, a0, 24 -; RV64IPN-NEXT: or a2, a2, a3 -; RV64IPN-NEXT: slli a3, a0, 8 -; RV64IPN-NEXT: lui a4, 4080 -; RV64IPN-NEXT: and a3, a3, a4 -; RV64IPN-NEXT: slli a0, a0, 24 -; RV64IPN-NEXT: or a0, a0, a3 -; RV64IPN-NEXT: or a0, a0, a2 -; RV64IPN-NEXT: lui a2, 61681 -; RV64IPN-NEXT: addiw a2, a2, -241 -; RV64IPN-NEXT: and a2, a0, a2 -; RV64IPN-NEXT: slli a2, a2, 4 -; RV64IPN-NEXT: lui a3, 241 -; RV64IPN-NEXT: addiw a3, a3, -241 -; RV64IPN-NEXT: slli a3, a3, 12 -; RV64IPN-NEXT: addi a3, a3, 240 -; RV64IPN-NEXT: and a0, a0, a3 -; RV64IPN-NEXT: srli a0, a0, 4 -; RV64IPN-NEXT: or a0, a0, a2 -; RV64IPN-NEXT: lui a2, 209715 -; RV64IPN-NEXT: addiw a2, a2, 819 -; RV64IPN-NEXT: and a2, a0, a2 -; RV64IPN-NEXT: slli a2, a2, 2 -; RV64IPN-NEXT: lui a3, 838861 -; RV64IPN-NEXT: addiw a3, a3, -820 -; RV64IPN-NEXT: and a0, a0, a3 -; RV64IPN-NEXT: srli a0, a0, 2 -; RV64IPN-NEXT: or a0, a0, a2 -; RV64IPN-NEXT: lui a2, 349525 -; RV64IPN-NEXT: addiw a2, a2, 1365 -; RV64IPN-NEXT: and a2, a0, a2 -; RV64IPN-NEXT: slli a2, a2, 1 -; RV64IPN-NEXT: lui a3, 699051 -; RV64IPN-NEXT: addiw a3, a3, -1366 -; RV64IPN-NEXT: and a0, a0, a3 -; RV64IPN-NEXT: srli a0, a0, 1 -; RV64IPN-NEXT: or a0, a0, a2 +; RV64IPN-NEXT: bitrevi a0, a0, 31 ; RV64IPN-NEXT: sw a0, 0(a1) ; RV64IPN-NEXT: ret ; @@ -369,194 +123,12 @@ ; ; RV64IP-LABEL: bitreverse_i64: ; RV64IP: # %bb.0: -; RV64IP-NEXT: srli a1, a0, 24 -; RV64IP-NEXT: lui a2, 4080 -; RV64IP-NEXT: and a1, a1, a2 -; RV64IP-NEXT: srli a2, a0, 8 -; RV64IP-NEXT: addi a3, zero, 255 -; RV64IP-NEXT: slli a4, a3, 24 -; RV64IP-NEXT: and a2, a2, a4 -; RV64IP-NEXT: or a1, a2, a1 -; RV64IP-NEXT: srli a2, a0, 40 -; RV64IP-NEXT: lui a4, 16 -; RV64IP-NEXT: addiw a4, a4, -256 -; RV64IP-NEXT: and a2, a2, a4 -; RV64IP-NEXT: srli a4, a0, 56 -; RV64IP-NEXT: or a2, a2, a4 -; RV64IP-NEXT: or a1, a1, a2 -; RV64IP-NEXT: slli a2, a0, 8 -; RV64IP-NEXT: slli a4, a3, 32 -; RV64IP-NEXT: and a2, a2, a4 -; RV64IP-NEXT: slli a4, a0, 24 -; RV64IP-NEXT: slli a5, a3, 40 -; RV64IP-NEXT: and a4, a4, a5 -; RV64IP-NEXT: or a2, a4, a2 -; RV64IP-NEXT: slli a4, a0, 40 -; RV64IP-NEXT: slli a3, a3, 48 -; RV64IP-NEXT: and a3, a4, a3 -; RV64IP-NEXT: slli a0, a0, 56 -; RV64IP-NEXT: or a0, a0, a3 -; RV64IP-NEXT: or a0, a0, a2 -; RV64IP-NEXT: or a0, a0, a1 -; RV64IP-NEXT: lui a1, 3855 -; RV64IP-NEXT: addiw a1, a1, 241 -; RV64IP-NEXT: slli a1, a1, 12 -; RV64IP-NEXT: addi a1, a1, -241 -; RV64IP-NEXT: slli a1, a1, 12 -; RV64IP-NEXT: addi a1, a1, 241 -; RV64IP-NEXT: slli a1, a1, 12 -; RV64IP-NEXT: addi a1, a1, -241 -; RV64IP-NEXT: and a1, a0, a1 -; RV64IP-NEXT: slli a1, a1, 4 -; RV64IP-NEXT: lui a2, 1044721 -; RV64IP-NEXT: addiw a2, a2, -241 -; RV64IP-NEXT: slli a2, a2, 12 -; RV64IP-NEXT: addi a2, a2, 241 -; RV64IP-NEXT: slli a2, a2, 12 -; RV64IP-NEXT: addi a2, a2, -241 -; RV64IP-NEXT: slli a2, a2, 12 -; RV64IP-NEXT: addi a2, a2, 240 -; RV64IP-NEXT: and a0, a0, a2 -; RV64IP-NEXT: srli a0, a0, 4 -; RV64IP-NEXT: or a0, a0, a1 -; RV64IP-NEXT: lui a1, 13107 -; RV64IP-NEXT: addiw a1, a1, 819 -; RV64IP-NEXT: slli a1, a1, 12 -; RV64IP-NEXT: addi a1, a1, 819 -; RV64IP-NEXT: slli a1, a1, 12 -; RV64IP-NEXT: addi a1, a1, 819 -; RV64IP-NEXT: slli a1, a1, 12 -; RV64IP-NEXT: addi a1, a1, 819 -; RV64IP-NEXT: and a1, a0, a1 -; RV64IP-NEXT: slli a1, a1, 2 -; RV64IP-NEXT: lui a2, 1035469 -; RV64IP-NEXT: addiw a2, a2, -819 -; RV64IP-NEXT: slli a2, a2, 12 -; RV64IP-NEXT: addi a2, a2, -819 -; RV64IP-NEXT: slli a2, a2, 12 -; RV64IP-NEXT: addi a2, a2, -819 -; RV64IP-NEXT: slli a2, a2, 12 -; RV64IP-NEXT: addi a2, a2, -820 -; RV64IP-NEXT: and a0, a0, a2 -; RV64IP-NEXT: srli a0, a0, 2 -; RV64IP-NEXT: or a0, a0, a1 -; RV64IP-NEXT: lui a1, 21845 -; RV64IP-NEXT: addiw a1, a1, 1365 -; RV64IP-NEXT: slli a1, a1, 12 -; RV64IP-NEXT: addi a1, a1, 1365 -; RV64IP-NEXT: slli a1, a1, 12 -; RV64IP-NEXT: addi a1, a1, 1365 -; RV64IP-NEXT: slli a1, a1, 12 -; RV64IP-NEXT: addi a1, a1, 1365 -; RV64IP-NEXT: and a1, a0, a1 -; RV64IP-NEXT: slli a1, a1, 1 -; RV64IP-NEXT: lui a2, 1026731 -; RV64IP-NEXT: addiw a2, a2, -1365 -; RV64IP-NEXT: slli a2, a2, 12 -; RV64IP-NEXT: addi a2, a2, -1365 -; RV64IP-NEXT: slli a2, a2, 12 -; RV64IP-NEXT: addi a2, a2, -1365 -; RV64IP-NEXT: slli a2, a2, 12 -; RV64IP-NEXT: addi a2, a2, -1366 -; RV64IP-NEXT: and a0, a0, a2 -; RV64IP-NEXT: srli a0, a0, 1 -; RV64IP-NEXT: or a0, a0, a1 +; RV64IP-NEXT: bitrevi a0, a0, 63 ; RV64IP-NEXT: ret ; ; RV64IPN-LABEL: bitreverse_i64: ; RV64IPN: # %bb.0: -; RV64IPN-NEXT: srli a1, a0, 24 -; RV64IPN-NEXT: lui a2, 4080 -; RV64IPN-NEXT: and a1, a1, a2 -; RV64IPN-NEXT: srli a2, a0, 8 -; RV64IPN-NEXT: addi a3, zero, 255 -; RV64IPN-NEXT: slli a4, a3, 24 -; RV64IPN-NEXT: and a2, a2, a4 -; RV64IPN-NEXT: or a1, a2, a1 -; RV64IPN-NEXT: srli a2, a0, 40 -; RV64IPN-NEXT: lui a4, 16 -; RV64IPN-NEXT: addiw a4, a4, -256 -; RV64IPN-NEXT: and a2, a2, a4 -; RV64IPN-NEXT: srli a4, a0, 56 -; RV64IPN-NEXT: or a2, a2, a4 -; RV64IPN-NEXT: or a1, a1, a2 -; RV64IPN-NEXT: slli a2, a0, 8 -; RV64IPN-NEXT: slli a4, a3, 32 -; RV64IPN-NEXT: and a2, a2, a4 -; RV64IPN-NEXT: slli a4, a0, 24 -; RV64IPN-NEXT: slli a5, a3, 40 -; RV64IPN-NEXT: and a4, a4, a5 -; RV64IPN-NEXT: or a2, a4, a2 -; RV64IPN-NEXT: slli a4, a0, 40 -; RV64IPN-NEXT: slli a3, a3, 48 -; RV64IPN-NEXT: and a3, a4, a3 -; RV64IPN-NEXT: slli a0, a0, 56 -; RV64IPN-NEXT: or a0, a0, a3 -; RV64IPN-NEXT: or a0, a0, a2 -; RV64IPN-NEXT: or a0, a0, a1 -; RV64IPN-NEXT: lui a1, 3855 -; RV64IPN-NEXT: addiw a1, a1, 241 -; RV64IPN-NEXT: slli a1, a1, 12 -; RV64IPN-NEXT: addi a1, a1, -241 -; RV64IPN-NEXT: slli a1, a1, 12 -; RV64IPN-NEXT: addi a1, a1, 241 -; RV64IPN-NEXT: slli a1, a1, 12 -; RV64IPN-NEXT: addi a1, a1, -241 -; RV64IPN-NEXT: and a1, a0, a1 -; RV64IPN-NEXT: slli a1, a1, 4 -; RV64IPN-NEXT: lui a2, 1044721 -; RV64IPN-NEXT: addiw a2, a2, -241 -; RV64IPN-NEXT: slli a2, a2, 12 -; RV64IPN-NEXT: addi a2, a2, 241 -; RV64IPN-NEXT: slli a2, a2, 12 -; RV64IPN-NEXT: addi a2, a2, -241 -; RV64IPN-NEXT: slli a2, a2, 12 -; RV64IPN-NEXT: addi a2, a2, 240 -; RV64IPN-NEXT: and a0, a0, a2 -; RV64IPN-NEXT: srli a0, a0, 4 -; RV64IPN-NEXT: or a0, a0, a1 -; RV64IPN-NEXT: lui a1, 13107 -; RV64IPN-NEXT: addiw a1, a1, 819 -; RV64IPN-NEXT: slli a1, a1, 12 -; RV64IPN-NEXT: addi a1, a1, 819 -; RV64IPN-NEXT: slli a1, a1, 12 -; RV64IPN-NEXT: addi a1, a1, 819 -; RV64IPN-NEXT: slli a1, a1, 12 -; RV64IPN-NEXT: addi a1, a1, 819 -; RV64IPN-NEXT: and a1, a0, a1 -; RV64IPN-NEXT: slli a1, a1, 2 -; RV64IPN-NEXT: lui a2, 1035469 -; RV64IPN-NEXT: addiw a2, a2, -819 -; RV64IPN-NEXT: slli a2, a2, 12 -; RV64IPN-NEXT: addi a2, a2, -819 -; RV64IPN-NEXT: slli a2, a2, 12 -; RV64IPN-NEXT: addi a2, a2, -819 -; RV64IPN-NEXT: slli a2, a2, 12 -; RV64IPN-NEXT: addi a2, a2, -820 -; RV64IPN-NEXT: and a0, a0, a2 -; RV64IPN-NEXT: srli a0, a0, 2 -; RV64IPN-NEXT: or a0, a0, a1 -; RV64IPN-NEXT: lui a1, 21845 -; RV64IPN-NEXT: addiw a1, a1, 1365 -; RV64IPN-NEXT: slli a1, a1, 12 -; RV64IPN-NEXT: addi a1, a1, 1365 -; RV64IPN-NEXT: slli a1, a1, 12 -; RV64IPN-NEXT: addi a1, a1, 1365 -; RV64IPN-NEXT: slli a1, a1, 12 -; RV64IPN-NEXT: addi a1, a1, 1365 -; RV64IPN-NEXT: and a1, a0, a1 -; RV64IPN-NEXT: slli a1, a1, 1 -; RV64IPN-NEXT: lui a2, 1026731 -; RV64IPN-NEXT: addiw a2, a2, -1365 -; RV64IPN-NEXT: slli a2, a2, 12 -; RV64IPN-NEXT: addi a2, a2, -1365 -; RV64IPN-NEXT: slli a2, a2, 12 -; RV64IPN-NEXT: addi a2, a2, -1365 -; RV64IPN-NEXT: slli a2, a2, 12 -; RV64IPN-NEXT: addi a2, a2, -1366 -; RV64IPN-NEXT: and a0, a0, a2 -; RV64IPN-NEXT: srli a0, a0, 1 -; RV64IPN-NEXT: or a0, a0, a1 +; RV64IPN-NEXT: bitrevi a0, a0, 63 ; RV64IPN-NEXT: ret ; ; RV64IBP-LABEL: bitreverse_i64: diff --git a/llvm/test/CodeGen/RISCV/rv64zpn-bswap.ll b/llvm/test/CodeGen/RISCV/rv64zpn-bswap.ll --- a/llvm/test/CodeGen/RISCV/rv64zpn-bswap.ll +++ b/llvm/test/CodeGen/RISCV/rv64zpn-bswap.ll @@ -20,22 +20,12 @@ ; ; RV64IP-LABEL: bswap_i16: ; RV64IP: # %bb.0: -; RV64IP-NEXT: srli a1, a0, 8 -; RV64IP-NEXT: slli a0, a0, 8 -; RV64IP-NEXT: or a0, a0, a1 -; RV64IP-NEXT: lui a1, 16 -; RV64IP-NEXT: addiw a1, a1, -1 -; RV64IP-NEXT: and a0, a0, a1 +; RV64IP-NEXT: swap8 a0, a0 ; RV64IP-NEXT: ret ; ; RV64IPN-LABEL: bswap_i16: ; RV64IPN: # %bb.0: -; RV64IPN-NEXT: srli a1, a0, 8 -; RV64IPN-NEXT: slli a0, a0, 8 -; RV64IPN-NEXT: or a0, a0, a1 -; RV64IPN-NEXT: lui a1, 16 -; RV64IPN-NEXT: addiw a1, a1, -1 -; RV64IPN-NEXT: and a0, a0, a1 +; RV64IPN-NEXT: swap8 a0, a0 ; RV64IPN-NEXT: ret ; ; RV64IBP-LABEL: bswap_i16: @@ -54,35 +44,15 @@ ; ; RV64IP-LABEL: bswap_i32: ; RV64IP: # %bb.0: -; RV64IP-NEXT: srliw a1, a0, 8 -; RV64IP-NEXT: lui a2, 16 -; RV64IP-NEXT: addiw a2, a2, -256 -; RV64IP-NEXT: and a1, a1, a2 -; RV64IP-NEXT: srliw a2, a0, 24 -; RV64IP-NEXT: or a1, a1, a2 -; RV64IP-NEXT: slli a2, a0, 8 -; RV64IP-NEXT: lui a3, 4080 -; RV64IP-NEXT: and a2, a2, a3 -; RV64IP-NEXT: slli a0, a0, 24 -; RV64IP-NEXT: or a0, a0, a2 -; RV64IP-NEXT: or a0, a0, a1 +; RV64IP-NEXT: swap8 a0, a0 +; RV64IP-NEXT: swap16 a0, a0 ; RV64IP-NEXT: sext.w a0, a0 ; RV64IP-NEXT: ret ; ; RV64IPN-LABEL: bswap_i32: ; RV64IPN: # %bb.0: -; RV64IPN-NEXT: srliw a1, a0, 8 -; RV64IPN-NEXT: lui a2, 16 -; RV64IPN-NEXT: addiw a2, a2, -256 -; RV64IPN-NEXT: and a1, a1, a2 -; RV64IPN-NEXT: srliw a2, a0, 24 -; RV64IPN-NEXT: or a1, a1, a2 -; RV64IPN-NEXT: slli a2, a0, 8 -; RV64IPN-NEXT: lui a3, 4080 -; RV64IPN-NEXT: and a2, a2, a3 -; RV64IPN-NEXT: slli a0, a0, 24 -; RV64IPN-NEXT: or a0, a0, a2 -; RV64IPN-NEXT: or a0, a0, a1 +; RV64IPN-NEXT: swap8 a0, a0 +; RV64IPN-NEXT: swap16 a0, a0 ; RV64IPN-NEXT: sext.w a0, a0 ; RV64IPN-NEXT: ret ; @@ -104,35 +74,15 @@ ; ; RV64IP-LABEL: bswap_i32_nosext: ; RV64IP: # %bb.0: -; RV64IP-NEXT: srliw a2, a0, 8 -; RV64IP-NEXT: lui a3, 16 -; RV64IP-NEXT: addiw a3, a3, -256 -; RV64IP-NEXT: and a2, a2, a3 -; RV64IP-NEXT: srliw a3, a0, 24 -; RV64IP-NEXT: or a2, a2, a3 -; RV64IP-NEXT: slli a3, a0, 8 -; RV64IP-NEXT: lui a4, 4080 -; RV64IP-NEXT: and a3, a3, a4 -; RV64IP-NEXT: slli a0, a0, 24 -; RV64IP-NEXT: or a0, a0, a3 -; RV64IP-NEXT: or a0, a0, a2 +; RV64IP-NEXT: swap8 a0, a0 +; RV64IP-NEXT: swap16 a0, a0 ; RV64IP-NEXT: sw a0, 0(a1) ; RV64IP-NEXT: ret ; ; RV64IPN-LABEL: bswap_i32_nosext: ; RV64IPN: # %bb.0: -; RV64IPN-NEXT: srliw a2, a0, 8 -; RV64IPN-NEXT: lui a3, 16 -; RV64IPN-NEXT: addiw a3, a3, -256 -; RV64IPN-NEXT: and a2, a2, a3 -; RV64IPN-NEXT: srliw a3, a0, 24 -; RV64IPN-NEXT: or a2, a2, a3 -; RV64IPN-NEXT: slli a3, a0, 8 -; RV64IPN-NEXT: lui a4, 4080 -; RV64IPN-NEXT: and a3, a3, a4 -; RV64IPN-NEXT: slli a0, a0, 24 -; RV64IPN-NEXT: or a0, a0, a3 -; RV64IPN-NEXT: or a0, a0, a2 +; RV64IPN-NEXT: swap8 a0, a0 +; RV64IPN-NEXT: swap16 a0, a0 ; RV64IPN-NEXT: sw a0, 0(a1) ; RV64IPN-NEXT: ret ; @@ -154,68 +104,16 @@ ; ; RV64IP-LABEL: bswap_i64: ; RV64IP: # %bb.0: -; RV64IP-NEXT: srli a1, a0, 24 -; RV64IP-NEXT: lui a2, 4080 -; RV64IP-NEXT: and a1, a1, a2 -; RV64IP-NEXT: srli a2, a0, 8 -; RV64IP-NEXT: addi a3, zero, 255 -; RV64IP-NEXT: slli a4, a3, 24 -; RV64IP-NEXT: and a2, a2, a4 -; RV64IP-NEXT: or a1, a2, a1 -; RV64IP-NEXT: srli a2, a0, 40 -; RV64IP-NEXT: lui a4, 16 -; RV64IP-NEXT: addiw a4, a4, -256 -; RV64IP-NEXT: and a2, a2, a4 -; RV64IP-NEXT: srli a4, a0, 56 -; RV64IP-NEXT: or a2, a2, a4 -; RV64IP-NEXT: or a1, a1, a2 -; RV64IP-NEXT: slli a2, a0, 8 -; RV64IP-NEXT: slli a4, a3, 32 -; RV64IP-NEXT: and a2, a2, a4 -; RV64IP-NEXT: slli a4, a0, 24 -; RV64IP-NEXT: slli a5, a3, 40 -; RV64IP-NEXT: and a4, a4, a5 -; RV64IP-NEXT: or a2, a4, a2 -; RV64IP-NEXT: slli a4, a0, 40 -; RV64IP-NEXT: slli a3, a3, 48 -; RV64IP-NEXT: and a3, a4, a3 -; RV64IP-NEXT: slli a0, a0, 56 -; RV64IP-NEXT: or a0, a0, a3 -; RV64IP-NEXT: or a0, a0, a2 -; RV64IP-NEXT: or a0, a0, a1 +; RV64IP-NEXT: swap8 a0, a0 +; RV64IP-NEXT: swap16 a0, a0 +; RV64IP-NEXT: pkbt32 a0, a0, a0 ; RV64IP-NEXT: ret ; ; RV64IPN-LABEL: bswap_i64: ; RV64IPN: # %bb.0: -; RV64IPN-NEXT: srli a1, a0, 24 -; RV64IPN-NEXT: lui a2, 4080 -; RV64IPN-NEXT: and a1, a1, a2 -; RV64IPN-NEXT: srli a2, a0, 8 -; RV64IPN-NEXT: addi a3, zero, 255 -; RV64IPN-NEXT: slli a4, a3, 24 -; RV64IPN-NEXT: and a2, a2, a4 -; RV64IPN-NEXT: or a1, a2, a1 -; RV64IPN-NEXT: srli a2, a0, 40 -; RV64IPN-NEXT: lui a4, 16 -; RV64IPN-NEXT: addiw a4, a4, -256 -; RV64IPN-NEXT: and a2, a2, a4 -; RV64IPN-NEXT: srli a4, a0, 56 -; RV64IPN-NEXT: or a2, a2, a4 -; RV64IPN-NEXT: or a1, a1, a2 -; RV64IPN-NEXT: slli a2, a0, 8 -; RV64IPN-NEXT: slli a4, a3, 32 -; RV64IPN-NEXT: and a2, a2, a4 -; RV64IPN-NEXT: slli a4, a0, 24 -; RV64IPN-NEXT: slli a5, a3, 40 -; RV64IPN-NEXT: and a4, a4, a5 -; RV64IPN-NEXT: or a2, a4, a2 -; RV64IPN-NEXT: slli a4, a0, 40 -; RV64IPN-NEXT: slli a3, a3, 48 -; RV64IPN-NEXT: and a3, a4, a3 -; RV64IPN-NEXT: slli a0, a0, 56 -; RV64IPN-NEXT: or a0, a0, a3 -; RV64IPN-NEXT: or a0, a0, a2 -; RV64IPN-NEXT: or a0, a0, a1 +; RV64IPN-NEXT: swap8 a0, a0 +; RV64IPN-NEXT: swap16 a0, a0 +; RV64IPN-NEXT: pkbt32 a0, a0, a0 ; RV64IPN-NEXT: ret ; ; RV64IBP-LABEL: bswap_i64: