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 @@ -1032,6 +1032,7 @@ setTargetDAGCombine(ISD::ROTR); setTargetDAGCombine(ISD::ANY_EXTEND); setTargetDAGCombine(ISD::INTRINSIC_WO_CHAIN); + setTargetDAGCombine(ISD::BSWAP); if (Subtarget.hasStdExtZfh()) setTargetDAGCombine(ISD::SIGN_EXTEND_INREG); if (Subtarget.hasStdExtF()) { @@ -8501,6 +8502,20 @@ } } } + case ISD::BSWAP: { + // Combine t2 = bswap t1; t3 = srl t2, x; bswap t3 + // to shl t1, x. + SDValue Srl = N->getOperand(0); + if (Srl->getOpcode() != ISD::SRL || !Srl.hasOneUse()) + return SDValue(); + SDValue BSwap = Srl->getOperand(0); + if (BSwap->getOpcode() != ISD::BSWAP || !BSwap.hasOneUse()) + return SDValue(); + SDLoc DL(N); + EVT VT = N->getValueType(0); + return DAG.getNode(ISD::SHL, DL, VT, BSwap->getOperand(0), + Srl->getOperand(1)); + } } return SDValue(); diff --git a/llvm/test/CodeGen/RISCV/bswap-bitreverse.ll b/llvm/test/CodeGen/RISCV/bswap-bitreverse.ll --- a/llvm/test/CodeGen/RISCV/bswap-bitreverse.ll +++ b/llvm/test/CodeGen/RISCV/bswap-bitreverse.ll @@ -848,18 +848,14 @@ ; ; RV32ZBKB-LABEL: test_bswap_bitreverse_i16: ; RV32ZBKB: # %bb.0: -; RV32ZBKB-NEXT: rev8 a0, a0 -; RV32ZBKB-NEXT: srli a0, a0, 16 -; RV32ZBKB-NEXT: rev8 a0, a0 +; RV32ZBKB-NEXT: slli a0, a0, 16 ; RV32ZBKB-NEXT: brev8 a0, a0 ; RV32ZBKB-NEXT: srli a0, a0, 16 ; RV32ZBKB-NEXT: ret ; ; RV64ZBKB-LABEL: test_bswap_bitreverse_i16: ; RV64ZBKB: # %bb.0: -; RV64ZBKB-NEXT: rev8 a0, a0 -; RV64ZBKB-NEXT: srli a0, a0, 48 -; RV64ZBKB-NEXT: rev8 a0, a0 +; RV64ZBKB-NEXT: slli a0, a0, 48 ; RV64ZBKB-NEXT: brev8 a0, a0 ; RV64ZBKB-NEXT: srli a0, a0, 48 ; RV64ZBKB-NEXT: ret @@ -977,9 +973,7 @@ ; ; RV64ZBKB-LABEL: test_bswap_bitreverse_i32: ; RV64ZBKB: # %bb.0: -; RV64ZBKB-NEXT: rev8 a0, a0 -; RV64ZBKB-NEXT: srli a0, a0, 32 -; RV64ZBKB-NEXT: rev8 a0, a0 +; RV64ZBKB-NEXT: slli a0, a0, 32 ; RV64ZBKB-NEXT: brev8 a0, a0 ; RV64ZBKB-NEXT: srli a0, a0, 32 ; RV64ZBKB-NEXT: ret @@ -1238,18 +1232,14 @@ ; ; RV32ZBKB-LABEL: test_bitreverse_bswap_i16: ; RV32ZBKB: # %bb.0: -; RV32ZBKB-NEXT: rev8 a0, a0 -; RV32ZBKB-NEXT: srli a0, a0, 16 -; RV32ZBKB-NEXT: rev8 a0, a0 +; RV32ZBKB-NEXT: slli a0, a0, 16 ; RV32ZBKB-NEXT: brev8 a0, a0 ; RV32ZBKB-NEXT: srli a0, a0, 16 ; RV32ZBKB-NEXT: ret ; ; RV64ZBKB-LABEL: test_bitreverse_bswap_i16: ; RV64ZBKB: # %bb.0: -; RV64ZBKB-NEXT: rev8 a0, a0 -; RV64ZBKB-NEXT: srli a0, a0, 48 -; RV64ZBKB-NEXT: rev8 a0, a0 +; RV64ZBKB-NEXT: slli a0, a0, 48 ; RV64ZBKB-NEXT: brev8 a0, a0 ; RV64ZBKB-NEXT: srli a0, a0, 48 ; RV64ZBKB-NEXT: ret @@ -1367,9 +1357,7 @@ ; ; RV64ZBKB-LABEL: test_bitreverse_bswap_i32: ; RV64ZBKB: # %bb.0: -; RV64ZBKB-NEXT: rev8 a0, a0 -; RV64ZBKB-NEXT: srli a0, a0, 32 -; RV64ZBKB-NEXT: rev8 a0, a0 +; RV64ZBKB-NEXT: slli a0, a0, 32 ; RV64ZBKB-NEXT: brev8 a0, a0 ; RV64ZBKB-NEXT: srli a0, a0, 32 ; RV64ZBKB-NEXT: ret