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 @@ -285,10 +285,13 @@ setOperationAction({ISD::SHL_PARTS, ISD::SRL_PARTS, ISD::SRA_PARTS}, XLenVT, Custom); - if (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb() || - Subtarget.hasVendorXTHeadBb()) { + if (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()) { if (Subtarget.is64Bit()) setOperationAction({ISD::ROTL, ISD::ROTR}, MVT::i32, Custom); + } else if (Subtarget.hasVendorXTHeadBb()) { + if (Subtarget.is64Bit()) + setOperationAction({ISD::ROTL, ISD::ROTR}, MVT::i32, Custom); + setOperationAction({ISD::ROTL, ISD::ROTR}, XLenVT, Custom); } else { setOperationAction({ISD::ROTL, ISD::ROTR}, XLenVT, Expand); } @@ -4418,6 +4421,15 @@ return lowerShiftRightParts(Op, DAG, true); case ISD::SRL_PARTS: return lowerShiftRightParts(Op, DAG, false); + case ISD::ROTL: + case ISD::ROTR: + assert(Subtarget.hasVendorXTHeadBb() && + !(Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb()) && + "Unexpected custom legalization"); + // XTHeadBb only supports rotate by constant. + if (!isa(Op.getOperand(1))) + return SDValue(); + return Op; case ISD::BITCAST: { SDLoc DL(Op); EVT VT = Op.getValueType(); @@ -9032,6 +9044,12 @@ case ISD::ROTR: assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() && "Unexpected custom legalisation"); + assert((Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb() || + Subtarget.hasVendorXTHeadBb()) && + "Unexpected custom legalization"); + if (!isa(N->getOperand(1)) && + !(Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb())) + return; Results.push_back(customLegalizeToWOp(N, DAG)); break; case ISD::CTTZ: diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td @@ -598,12 +598,6 @@ // it can be implemented with th.srri by negating the immediate. def : Pat<(rotl GPR:$rs1, uimmlog2xlen:$shamt), (TH_SRRI GPR:$rs1, (ImmSubFromXLen uimmlog2xlen:$shamt))>; -def : Pat<(rotr GPR:$rs1, GPR:$rs2), - (OR (SRL GPR:$rs1, GPR:$rs2), - (SLL GPR:$rs1, (SUB X0, GPR:$rs2)))>; -def : Pat<(rotl GPR:$rs1, GPR:$rs2), - (OR (SLL GPR:$rs1, GPR:$rs2), - (SRL GPR:$rs1, (SUB X0, GPR:$rs2)))>; def : Pat<(sext_inreg GPR:$rs1, i32), (TH_EXT GPR:$rs1, 31, 0)>; def : Pat<(sext_inreg GPR:$rs1, i16), (TH_EXT GPR:$rs1, 15, 0)>; def : Pat<(sext_inreg GPR:$rs1, i8), (TH_EXT GPR:$rs1, 7, 0)>; @@ -617,12 +611,6 @@ def : PatGprImm; def : Pat<(riscv_rolw GPR:$rs1, uimm5:$rs2), (TH_SRRIW GPR:$rs1, (ImmSubFrom32 uimm5:$rs2))>; -def : Pat<(riscv_rorw i64:$rs1, i64:$rs2), - (OR (SRLW i64:$rs1, i64:$rs2), - (SLLW i64:$rs1, (SUB X0, i64:$rs2)))>; -def : Pat<(riscv_rolw i64:$rs1, i64:$rs2), - (OR (SLLW i64:$rs1, i64:$rs2), - (SRLW i64:$rs1, (SUB X0, i64:$rs2)))>; def : Pat<(sra (bswap i64:$rs1), (i64 32)), (TH_REVW i64:$rs1)>; def : Pat<(binop_allwusers (bswap i64:$rs1), (i64 32)), diff --git a/llvm/test/CodeGen/RISCV/rotl-rotr.ll b/llvm/test/CodeGen/RISCV/rotl-rotr.ll --- a/llvm/test/CodeGen/RISCV/rotl-rotr.ll +++ b/llvm/test/CodeGen/RISCV/rotl-rotr.ll @@ -56,7 +56,7 @@ ; RV64XTHEADBB-LABEL: rotl_32: ; RV64XTHEADBB: # %bb.0: ; RV64XTHEADBB-NEXT: sllw a2, a0, a1 -; RV64XTHEADBB-NEXT: neg a1, a1 +; RV64XTHEADBB-NEXT: negw a1, a1 ; RV64XTHEADBB-NEXT: srlw a0, a0, a1 ; RV64XTHEADBB-NEXT: or a0, a2, a0 ; RV64XTHEADBB-NEXT: ret @@ -105,7 +105,7 @@ ; RV64XTHEADBB-LABEL: rotr_32: ; RV64XTHEADBB: # %bb.0: ; RV64XTHEADBB-NEXT: srlw a2, a0, a1 -; RV64XTHEADBB-NEXT: neg a1, a1 +; RV64XTHEADBB-NEXT: negw a1, a1 ; RV64XTHEADBB-NEXT: sllw a0, a0, a1 ; RV64XTHEADBB-NEXT: or a0, a2, a0 ; RV64XTHEADBB-NEXT: ret @@ -253,7 +253,7 @@ ; RV64XTHEADBB-LABEL: rotl_64: ; RV64XTHEADBB: # %bb.0: ; RV64XTHEADBB-NEXT: sll a2, a0, a1 -; RV64XTHEADBB-NEXT: neg a1, a1 +; RV64XTHEADBB-NEXT: negw a1, a1 ; RV64XTHEADBB-NEXT: srl a0, a0, a1 ; RV64XTHEADBB-NEXT: or a0, a2, a0 ; RV64XTHEADBB-NEXT: ret @@ -401,7 +401,7 @@ ; RV64XTHEADBB-LABEL: rotr_64: ; RV64XTHEADBB: # %bb.0: ; RV64XTHEADBB-NEXT: srl a2, a0, a1 -; RV64XTHEADBB-NEXT: neg a1, a1 +; RV64XTHEADBB-NEXT: negw a1, a1 ; RV64XTHEADBB-NEXT: sll a0, a0, a1 ; RV64XTHEADBB-NEXT: or a0, a2, a0 ; RV64XTHEADBB-NEXT: ret @@ -450,7 +450,7 @@ ; RV64XTHEADBB-LABEL: rotl_32_mask: ; RV64XTHEADBB: # %bb.0: ; RV64XTHEADBB-NEXT: sllw a2, a0, a1 -; RV64XTHEADBB-NEXT: neg a1, a1 +; RV64XTHEADBB-NEXT: negw a1, a1 ; RV64XTHEADBB-NEXT: srlw a0, a0, a1 ; RV64XTHEADBB-NEXT: or a0, a2, a0 ; RV64XTHEADBB-NEXT: ret @@ -500,7 +500,7 @@ ; RV64XTHEADBB-LABEL: rotl_32_mask_and_63_and_31: ; RV64XTHEADBB: # %bb.0: ; RV64XTHEADBB-NEXT: sllw a2, a0, a1 -; RV64XTHEADBB-NEXT: neg a1, a1 +; RV64XTHEADBB-NEXT: negw a1, a1 ; RV64XTHEADBB-NEXT: srlw a0, a0, a1 ; RV64XTHEADBB-NEXT: or a0, a2, a0 ; RV64XTHEADBB-NEXT: ret @@ -548,7 +548,7 @@ ; RV64XTHEADBB-LABEL: rotl_32_mask_or_64_or_32: ; RV64XTHEADBB: # %bb.0: ; RV64XTHEADBB-NEXT: sllw a2, a0, a1 -; RV64XTHEADBB-NEXT: neg a1, a1 +; RV64XTHEADBB-NEXT: negw a1, a1 ; RV64XTHEADBB-NEXT: srlw a0, a0, a1 ; RV64XTHEADBB-NEXT: or a0, a2, a0 ; RV64XTHEADBB-NEXT: ret @@ -599,7 +599,7 @@ ; RV64XTHEADBB-LABEL: rotr_32_mask: ; RV64XTHEADBB: # %bb.0: ; RV64XTHEADBB-NEXT: srlw a2, a0, a1 -; RV64XTHEADBB-NEXT: neg a1, a1 +; RV64XTHEADBB-NEXT: negw a1, a1 ; RV64XTHEADBB-NEXT: sllw a0, a0, a1 ; RV64XTHEADBB-NEXT: or a0, a2, a0 ; RV64XTHEADBB-NEXT: ret @@ -649,7 +649,7 @@ ; RV64XTHEADBB-LABEL: rotr_32_mask_and_63_and_31: ; RV64XTHEADBB: # %bb.0: ; RV64XTHEADBB-NEXT: srlw a2, a0, a1 -; RV64XTHEADBB-NEXT: neg a1, a1 +; RV64XTHEADBB-NEXT: negw a1, a1 ; RV64XTHEADBB-NEXT: sllw a0, a0, a1 ; RV64XTHEADBB-NEXT: or a0, a2, a0 ; RV64XTHEADBB-NEXT: ret @@ -695,7 +695,7 @@ ; RV64XTHEADBB-LABEL: rotr_32_mask_or_64_or_32: ; RV64XTHEADBB: # %bb.0: ; RV64XTHEADBB-NEXT: srlw a2, a0, a1 -; RV64XTHEADBB-NEXT: neg a1, a1 +; RV64XTHEADBB-NEXT: negw a1, a1 ; RV64XTHEADBB-NEXT: sllw a0, a0, a1 ; RV64XTHEADBB-NEXT: or a0, a2, a0 ; RV64XTHEADBB-NEXT: ret @@ -839,7 +839,7 @@ ; RV64XTHEADBB-LABEL: rotl_64_mask: ; RV64XTHEADBB: # %bb.0: ; RV64XTHEADBB-NEXT: sll a2, a0, a1 -; RV64XTHEADBB-NEXT: neg a1, a1 +; RV64XTHEADBB-NEXT: negw a1, a1 ; RV64XTHEADBB-NEXT: srl a0, a0, a1 ; RV64XTHEADBB-NEXT: or a0, a2, a0 ; RV64XTHEADBB-NEXT: ret @@ -985,7 +985,7 @@ ; RV64XTHEADBB-LABEL: rotl_64_mask_and_127_and_63: ; RV64XTHEADBB: # %bb.0: ; RV64XTHEADBB-NEXT: sll a2, a0, a1 -; RV64XTHEADBB-NEXT: neg a1, a1 +; RV64XTHEADBB-NEXT: negw a1, a1 ; RV64XTHEADBB-NEXT: srl a0, a0, a1 ; RV64XTHEADBB-NEXT: or a0, a2, a0 ; RV64XTHEADBB-NEXT: ret @@ -1035,7 +1035,7 @@ ; RV64XTHEADBB-LABEL: rotl_64_mask_or_128_or_64: ; RV64XTHEADBB: # %bb.0: ; RV64XTHEADBB-NEXT: sll a2, a0, a1 -; RV64XTHEADBB-NEXT: neg a1, a1 +; RV64XTHEADBB-NEXT: negw a1, a1 ; RV64XTHEADBB-NEXT: srl a0, a0, a1 ; RV64XTHEADBB-NEXT: or a0, a2, a0 ; RV64XTHEADBB-NEXT: ret @@ -1179,7 +1179,7 @@ ; RV64XTHEADBB-LABEL: rotr_64_mask: ; RV64XTHEADBB: # %bb.0: ; RV64XTHEADBB-NEXT: srl a2, a0, a1 -; RV64XTHEADBB-NEXT: neg a1, a1 +; RV64XTHEADBB-NEXT: negw a1, a1 ; RV64XTHEADBB-NEXT: sll a0, a0, a1 ; RV64XTHEADBB-NEXT: or a0, a2, a0 ; RV64XTHEADBB-NEXT: ret @@ -1325,7 +1325,7 @@ ; RV64XTHEADBB-LABEL: rotr_64_mask_and_127_and_63: ; RV64XTHEADBB: # %bb.0: ; RV64XTHEADBB-NEXT: srl a2, a0, a1 -; RV64XTHEADBB-NEXT: neg a1, a1 +; RV64XTHEADBB-NEXT: negw a1, a1 ; RV64XTHEADBB-NEXT: sll a0, a0, a1 ; RV64XTHEADBB-NEXT: or a0, a2, a0 ; RV64XTHEADBB-NEXT: ret @@ -1371,7 +1371,7 @@ ; RV64XTHEADBB-LABEL: rotr_64_mask_or_128_or_64: ; RV64XTHEADBB: # %bb.0: ; RV64XTHEADBB-NEXT: srl a2, a0, a1 -; RV64XTHEADBB-NEXT: neg a1, a1 +; RV64XTHEADBB-NEXT: negw a1, a1 ; RV64XTHEADBB-NEXT: sll a0, a0, a1 ; RV64XTHEADBB-NEXT: or a0, a2, a0 ; RV64XTHEADBB-NEXT: ret @@ -1423,11 +1423,10 @@ ; ; RV32XTHEADBB-LABEL: rotl_32_mask_shared: ; RV32XTHEADBB: # %bb.0: -; RV32XTHEADBB-NEXT: andi a3, a2, 31 -; RV32XTHEADBB-NEXT: sll a4, a0, a3 -; RV32XTHEADBB-NEXT: neg a3, a3 -; RV32XTHEADBB-NEXT: srl a0, a0, a3 -; RV32XTHEADBB-NEXT: or a0, a4, a0 +; RV32XTHEADBB-NEXT: sll a3, a0, a2 +; RV32XTHEADBB-NEXT: neg a4, a2 +; RV32XTHEADBB-NEXT: srl a0, a0, a4 +; RV32XTHEADBB-NEXT: or a0, a3, a0 ; RV32XTHEADBB-NEXT: sll a1, a1, a2 ; RV32XTHEADBB-NEXT: add a0, a0, a1 ; RV32XTHEADBB-NEXT: ret @@ -1435,7 +1434,7 @@ ; RV64XTHEADBB-LABEL: rotl_32_mask_shared: ; RV64XTHEADBB: # %bb.0: ; RV64XTHEADBB-NEXT: sllw a3, a0, a2 -; RV64XTHEADBB-NEXT: neg a4, a2 +; RV64XTHEADBB-NEXT: negw a4, a2 ; RV64XTHEADBB-NEXT: srlw a0, a0, a4 ; RV64XTHEADBB-NEXT: or a0, a3, a0 ; RV64XTHEADBB-NEXT: sllw a1, a1, a2 @@ -1600,11 +1599,10 @@ ; ; RV64XTHEADBB-LABEL: rotl_64_mask_shared: ; RV64XTHEADBB: # %bb.0: -; RV64XTHEADBB-NEXT: andi a3, a2, 63 -; RV64XTHEADBB-NEXT: sll a4, a0, a3 -; RV64XTHEADBB-NEXT: neg a3, a3 -; RV64XTHEADBB-NEXT: srl a0, a0, a3 -; RV64XTHEADBB-NEXT: or a0, a4, a0 +; RV64XTHEADBB-NEXT: sll a3, a0, a2 +; RV64XTHEADBB-NEXT: negw a4, a2 +; RV64XTHEADBB-NEXT: srl a0, a0, a4 +; RV64XTHEADBB-NEXT: or a0, a3, a0 ; RV64XTHEADBB-NEXT: sll a1, a1, a2 ; RV64XTHEADBB-NEXT: add a0, a0, a1 ; RV64XTHEADBB-NEXT: ret @@ -1653,11 +1651,10 @@ ; ; RV32XTHEADBB-LABEL: rotr_32_mask_shared: ; RV32XTHEADBB: # %bb.0: -; RV32XTHEADBB-NEXT: andi a3, a2, 31 -; RV32XTHEADBB-NEXT: srl a4, a0, a3 -; RV32XTHEADBB-NEXT: neg a3, a3 -; RV32XTHEADBB-NEXT: sll a0, a0, a3 -; RV32XTHEADBB-NEXT: or a0, a4, a0 +; RV32XTHEADBB-NEXT: srl a3, a0, a2 +; RV32XTHEADBB-NEXT: neg a4, a2 +; RV32XTHEADBB-NEXT: sll a0, a0, a4 +; RV32XTHEADBB-NEXT: or a0, a3, a0 ; RV32XTHEADBB-NEXT: sll a1, a1, a2 ; RV32XTHEADBB-NEXT: add a0, a0, a1 ; RV32XTHEADBB-NEXT: ret @@ -1665,7 +1662,7 @@ ; RV64XTHEADBB-LABEL: rotr_32_mask_shared: ; RV64XTHEADBB: # %bb.0: ; RV64XTHEADBB-NEXT: srlw a3, a0, a2 -; RV64XTHEADBB-NEXT: neg a4, a2 +; RV64XTHEADBB-NEXT: negw a4, a2 ; RV64XTHEADBB-NEXT: sllw a0, a0, a4 ; RV64XTHEADBB-NEXT: or a0, a3, a0 ; RV64XTHEADBB-NEXT: sllw a1, a1, a2 @@ -1828,11 +1825,10 @@ ; ; RV64XTHEADBB-LABEL: rotr_64_mask_shared: ; RV64XTHEADBB: # %bb.0: -; RV64XTHEADBB-NEXT: andi a3, a2, 63 -; RV64XTHEADBB-NEXT: srl a4, a0, a3 -; RV64XTHEADBB-NEXT: neg a3, a3 -; RV64XTHEADBB-NEXT: sll a0, a0, a3 -; RV64XTHEADBB-NEXT: or a0, a4, a0 +; RV64XTHEADBB-NEXT: srl a3, a0, a2 +; RV64XTHEADBB-NEXT: negw a4, a2 +; RV64XTHEADBB-NEXT: sll a0, a0, a4 +; RV64XTHEADBB-NEXT: or a0, a3, a0 ; RV64XTHEADBB-NEXT: sll a1, a1, a2 ; RV64XTHEADBB-NEXT: add a0, a0, a1 ; RV64XTHEADBB-NEXT: ret @@ -1885,7 +1881,6 @@ ; ; RV32XTHEADBB-LABEL: rotl_32_mask_multiple: ; RV32XTHEADBB: # %bb.0: -; RV32XTHEADBB-NEXT: andi a2, a2, 31 ; RV32XTHEADBB-NEXT: sll a3, a0, a2 ; RV32XTHEADBB-NEXT: neg a4, a2 ; RV32XTHEADBB-NEXT: srl a0, a0, a4 @@ -1898,9 +1893,8 @@ ; ; RV64XTHEADBB-LABEL: rotl_32_mask_multiple: ; RV64XTHEADBB: # %bb.0: -; RV64XTHEADBB-NEXT: andi a2, a2, 31 ; RV64XTHEADBB-NEXT: sllw a3, a0, a2 -; RV64XTHEADBB-NEXT: neg a4, a2 +; RV64XTHEADBB-NEXT: negw a4, a2 ; RV64XTHEADBB-NEXT: srlw a0, a0, a4 ; RV64XTHEADBB-NEXT: or a0, a3, a0 ; RV64XTHEADBB-NEXT: sllw a2, a1, a2 @@ -2071,9 +2065,8 @@ ; ; RV64XTHEADBB-LABEL: rotl_64_mask_multiple: ; RV64XTHEADBB: # %bb.0: -; RV64XTHEADBB-NEXT: andi a2, a2, 63 ; RV64XTHEADBB-NEXT: sll a3, a0, a2 -; RV64XTHEADBB-NEXT: neg a4, a2 +; RV64XTHEADBB-NEXT: negw a4, a2 ; RV64XTHEADBB-NEXT: srl a0, a0, a4 ; RV64XTHEADBB-NEXT: or a0, a3, a0 ; RV64XTHEADBB-NEXT: sll a2, a1, a2 @@ -2129,7 +2122,6 @@ ; ; RV32XTHEADBB-LABEL: rotr_32_mask_multiple: ; RV32XTHEADBB: # %bb.0: -; RV32XTHEADBB-NEXT: andi a2, a2, 31 ; RV32XTHEADBB-NEXT: srl a3, a0, a2 ; RV32XTHEADBB-NEXT: neg a4, a2 ; RV32XTHEADBB-NEXT: sll a0, a0, a4 @@ -2142,9 +2134,8 @@ ; ; RV64XTHEADBB-LABEL: rotr_32_mask_multiple: ; RV64XTHEADBB: # %bb.0: -; RV64XTHEADBB-NEXT: andi a2, a2, 31 ; RV64XTHEADBB-NEXT: srlw a3, a0, a2 -; RV64XTHEADBB-NEXT: neg a4, a2 +; RV64XTHEADBB-NEXT: negw a4, a2 ; RV64XTHEADBB-NEXT: sllw a0, a0, a4 ; RV64XTHEADBB-NEXT: or a0, a3, a0 ; RV64XTHEADBB-NEXT: srlw a2, a1, a2 @@ -2313,9 +2304,8 @@ ; ; RV64XTHEADBB-LABEL: rotr_64_mask_multiple: ; RV64XTHEADBB: # %bb.0: -; RV64XTHEADBB-NEXT: andi a2, a2, 63 ; RV64XTHEADBB-NEXT: srl a3, a0, a2 -; RV64XTHEADBB-NEXT: neg a4, a2 +; RV64XTHEADBB-NEXT: negw a4, a2 ; RV64XTHEADBB-NEXT: sll a0, a0, a4 ; RV64XTHEADBB-NEXT: or a0, a3, a0 ; RV64XTHEADBB-NEXT: srl a2, a1, a2 @@ -2467,7 +2457,7 @@ ; RV64XTHEADBB-LABEL: rotl_64_zext: ; RV64XTHEADBB: # %bb.0: ; RV64XTHEADBB-NEXT: sll a2, a0, a1 -; RV64XTHEADBB-NEXT: neg a1, a1 +; RV64XTHEADBB-NEXT: negw a1, a1 ; RV64XTHEADBB-NEXT: srl a0, a0, a1 ; RV64XTHEADBB-NEXT: or a0, a2, a0 ; RV64XTHEADBB-NEXT: ret @@ -2617,7 +2607,7 @@ ; RV64XTHEADBB-LABEL: rotr_64_zext: ; RV64XTHEADBB: # %bb.0: ; RV64XTHEADBB-NEXT: srl a2, a0, a1 -; RV64XTHEADBB-NEXT: neg a1, a1 +; RV64XTHEADBB-NEXT: negw a1, a1 ; RV64XTHEADBB-NEXT: sll a0, a0, a1 ; RV64XTHEADBB-NEXT: or a0, a2, a0 ; RV64XTHEADBB-NEXT: ret