From d05eae7a7b24444c676238383037552816072052 Mon Sep 17 00:00:00 2001 From: Alex Bradbury Date: Sat, 12 Jan 2019 07:32:31 +0000 Subject: [PATCH] [RISCV] Add patterns for RV64I SLLW/SRLW/SRAW instructions This restores support for selecting the SLLW/SRLW/SRAW instructions, which was removed in rL348067 as the previous patterns made some unsafe assumptions. Also see the related llvm-dev discussion Ultimately I didn't introduce a custom SelectionDAG node, but instead added a DAG combine that inserts an AssertZext i5 on the shift amount for an i32 variable-length shift and also added an ANY_EXTEND DAG-combine which will instead produce a SIGN_EXTEND for an i32 variable-length shift, increasing the opportunity to safely select SLLW/SRLW/SRAW. There are obviously different ways of addressing this (a number discussed in the llvm-dev thread), so I'd welcome further feedback and comments. Note that there are now some cases in test/CodeGen/RISCV/rv64i-exhaustive-w-insts.ll where sraw/srlw/sllw is selected even though sra/srl/sll could be used without any extra instructions. Given both are semantically equivalent, there doesn't seem a good reason to prefer one vs the other. Given that would require more logic to still select sra/srl/sll in those cases, I've left it preferring the *w variants. Differential Revision: https://reviews.llvm.org/D56264 llvm-svn: 350992 --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 51 +++++ llvm/lib/Target/RISCV/RISCVInstrInfo.td | 47 +++- llvm/test/CodeGen/RISCV/alu32.ll | 13 +- llvm/test/CodeGen/RISCV/alu64.ll | 17 +- .../test/CodeGen/RISCV/rv64i-exhaustive-w-insts.ll | 241 +++++++-------------- 5 files changed, 184 insertions(+), 185 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index e78085e..ca6fbb1 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -80,6 +80,13 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, for (auto VT : {MVT::i1, MVT::i8, MVT::i16}) setOperationAction(ISD::SIGN_EXTEND_INREG, VT, Expand); + if (Subtarget.is64Bit()) { + setTargetDAGCombine(ISD::SHL); + setTargetDAGCombine(ISD::SRL); + setTargetDAGCombine(ISD::SRA); + setTargetDAGCombine(ISD::ANY_EXTEND); + } + if (!Subtarget.hasStdExtM()) { setOperationAction(ISD::MUL, XLenVT, Expand); setOperationAction(ISD::MULHS, XLenVT, Expand); @@ -506,11 +513,55 @@ SDValue RISCVTargetLowering::lowerRETURNADDR(SDValue Op, return DAG.getCopyFromReg(DAG.getEntryNode(), DL, Reg, XLenVT); } +// Return true if the given node is a shift with a non-constant shift amount. +static bool isVariableShift(SDValue Val) { + switch (Val.getOpcode()) { + default: + return false; + case ISD::SHL: + case ISD::SRA: + case ISD::SRL: + return Val.getOperand(1).getOpcode() != ISD::Constant; + } +} + SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const { + SelectionDAG &DAG = DCI.DAG; + switch (N->getOpcode()) { default: break; + case ISD::SHL: + case ISD::SRL: + case ISD::SRA: { + assert(Subtarget.getXLen() == 64 && "Combine should be 64-bit only"); + if (!DCI.isBeforeLegalize()) + break; + SDValue RHS = N->getOperand(1); + if (N->getValueType(0) != MVT::i32 || RHS->getOpcode() == ISD::Constant || + (RHS->getOpcode() == ISD::AssertZext && + cast(RHS->getOperand(1))->getVT().getSizeInBits() <= 5)) + break; + SDValue LHS = N->getOperand(0); + SDLoc DL(N); + SDValue NewRHS = + DAG.getNode(ISD::AssertZext, DL, RHS.getValueType(), RHS, + DAG.getValueType(EVT::getIntegerVT(*DAG.getContext(), 5))); + return DCI.CombineTo( + N, DAG.getNode(N->getOpcode(), DL, LHS.getValueType(), LHS, NewRHS)); + } + case ISD::ANY_EXTEND: { + // If any-extending an i32 variable-length shift to i64, then instead + // sign-extend in order to increase the chance of being able to select the + // sllw/srlw/sraw instruction. + SDValue Src = N->getOperand(0); + if (N->getValueType(0) != MVT::i64 || Src.getValueType() != MVT::i32 || + !isVariableShift(Src)) + break; + SDLoc DL(N); + return DCI.CombineTo(N, DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i64, Src)); + } case RISCVISD::SplitF64: { // If the input to SplitF64 is just BuildPairF64 then the operation is // redundant. Instead, use BuildPairF64's operands directly. diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index 0123131..d7cc13d 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -654,6 +654,30 @@ class PatGprUimmLog2XLen def IsOrAdd: PatFrag<(ops node:$A, node:$B), (or node:$A, node:$B), [{ return isOrEquivalentToAdd(N); }]>; +def assertsexti32 : PatFrag<(ops node:$src), (assertsext node:$src), [{ + return cast(N->getOperand(1))->getVT() == MVT::i32; +}]>; +def sexti32 : PatFrags<(ops node:$src), + [(sext_inreg node:$src, i32), + (assertsexti32 node:$src)]>; +def assertzexti32 : PatFrag<(ops node:$src), (assertzext node:$src), [{ + return cast(N->getOperand(1))->getVT() == MVT::i32; +}]>; +def assertzexti5 : PatFrag<(ops node:$src), (assertzext node:$src), [{ + return cast(N->getOperand(1))->getVT().getSizeInBits() <= 5; +}]>; +def zexti32 : PatFrags<(ops node:$src), + [(and node:$src, 0xffffffff), + (assertzexti32 node:$src)]>; +// Defines a legal mask for (assertzexti5 (and src, mask)) to be combinable +// with a shiftw operation. The mask mustn't modify the lower 5 bits or the +// upper 32 bits. +def shiftwamt_mask : ImmLeaf(Imm) >= 5 && isUInt<32>(Imm); +}]>; +def shiftwamt : PatFrags<(ops node:$src), + [(assertzexti5 (and node:$src, shiftwamt_mask)), + (assertzexti5 node:$src)]>; /// Immediates @@ -911,7 +935,28 @@ def : Pat<(sext_inreg (shl GPR:$rs1, uimm5:$shamt), i32), def : Pat<(sra (sext_inreg GPR:$rs1, i32), uimm5:$shamt), (SRAIW GPR:$rs1, uimm5:$shamt)>; -// TODO: patterns for SLLW/SRLW/SRAW. +// For variable-length shifts, we rely on assertzexti5 being inserted during +// lowering (see RISCVTargetLowering::PerformDAGCombine). This enables us to +// guarantee that selecting a 32-bit variable shift is legal (as the variable +// shift is known to be <= 32). We must also be careful not to create +// semantically incorrect patterns. For instance, selecting SRLW for +// (srl (zexti32 GPR:$rs1), (shiftwamt GPR:$rs2)), +// is not guaranteed to be safe, as we don't know whether the upper 32-bits of +// the result are used or not (in the case where rs2=0, this is a +// sign-extension operation). + +def : Pat<(sext_inreg (shl GPR:$rs1, (shiftwamt GPR:$rs2)), i32), + (SLLW GPR:$rs1, GPR:$rs2)>; +def : Pat<(zexti32 (shl GPR:$rs1, (shiftwamt GPR:$rs2))), + (SRLI (SLLI (SLLW GPR:$rs1, GPR:$rs2), 32), 32)>; + +def : Pat<(sext_inreg (srl (zexti32 GPR:$rs1), (shiftwamt GPR:$rs2)), i32), + (SRLW GPR:$rs1, GPR:$rs2)>; +def : Pat<(zexti32 (srl (zexti32 GPR:$rs1), (shiftwamt GPR:$rs2))), + (SRLI (SLLI (SRLW GPR:$rs1, GPR:$rs2), 32), 32)>; + +def : Pat<(sra (sexti32 GPR:$rs1), (shiftwamt GPR:$rs2)), + (SRAW GPR:$rs1, GPR:$rs2)>; /// Loads diff --git a/llvm/test/CodeGen/RISCV/alu32.ll b/llvm/test/CodeGen/RISCV/alu32.ll index 3776e53..d6f667c 100644 --- a/llvm/test/CodeGen/RISCV/alu32.ll +++ b/llvm/test/CodeGen/RISCV/alu32.ll @@ -181,7 +181,7 @@ define i32 @sll(i32 %a, i32 %b) nounwind { ; ; RV64I-LABEL: sll: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: ret %1 = shl i32 %a, %b ret i32 %1 @@ -235,8 +235,6 @@ define i32 @xor(i32 %a, i32 %b) nounwind { ret i32 %1 } -; TODO: should select srlw for RV64. - define i32 @srl(i32 %a, i32 %b) nounwind { ; RV32I-LABEL: srl: ; RV32I: # %bb.0: @@ -245,16 +243,12 @@ define i32 @srl(i32 %a, i32 %b) nounwind { ; ; RV64I-LABEL: srl: ; RV64I: # %bb.0: -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: srli a0, a0, 32 -; RV64I-NEXT: srl a0, a0, a1 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: ret %1 = lshr i32 %a, %b ret i32 %1 } -; TODO: should select sraw for RV64. - define i32 @sra(i32 %a, i32 %b) nounwind { ; RV32I-LABEL: sra: ; RV32I: # %bb.0: @@ -263,8 +257,7 @@ define i32 @sra(i32 %a, i32 %b) nounwind { ; ; RV64I-LABEL: sra: ; RV64I: # %bb.0: -; RV64I-NEXT: sext.w a0, a0 -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: ret %1 = ashr i32 %a, %b ret i32 %1 diff --git a/llvm/test/CodeGen/RISCV/alu64.ll b/llvm/test/CodeGen/RISCV/alu64.ll index 021211b..e66d1d6 100644 --- a/llvm/test/CodeGen/RISCV/alu64.ll +++ b/llvm/test/CodeGen/RISCV/alu64.ll @@ -444,13 +444,10 @@ define signext i32 @subw(i32 signext %a, i32 signext %b) { ret i32 %1 } -; TODO: should select sllw for RV64. - define signext i32 @sllw(i32 signext %a, i32 zeroext %b) { ; RV64I-LABEL: sllw: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 -; RV64I-NEXT: sext.w a0, a0 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: ret ; ; RV32I-LABEL: sllw: @@ -461,15 +458,10 @@ define signext i32 @sllw(i32 signext %a, i32 zeroext %b) { ret i32 %1 } -; TODO: should select srlw for RV64. - define signext i32 @srlw(i32 signext %a, i32 zeroext %b) { ; RV64I-LABEL: srlw: ; RV64I: # %bb.0: -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: srli a0, a0, 32 -; RV64I-NEXT: srl a0, a0, a1 -; RV64I-NEXT: sext.w a0, a0 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: ret ; ; RV32I-LABEL: srlw: @@ -480,13 +472,10 @@ define signext i32 @srlw(i32 signext %a, i32 zeroext %b) { ret i32 %1 } -; TODO: should select sraw for RV64. - define signext i32 @sraw(i64 %a, i32 zeroext %b) { ; RV64I-LABEL: sraw: ; RV64I: # %bb.0: -; RV64I-NEXT: sext.w a0, a0 -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: ret ; ; RV32I-LABEL: sraw: diff --git a/llvm/test/CodeGen/RISCV/rv64i-exhaustive-w-insts.ll b/llvm/test/CodeGen/RISCV/rv64i-exhaustive-w-insts.ll index 52a59c0..b7f513d 100644 --- a/llvm/test/CodeGen/RISCV/rv64i-exhaustive-w-insts.ll +++ b/llvm/test/CodeGen/RISCV/rv64i-exhaustive-w-insts.ll @@ -546,7 +546,7 @@ define zeroext i32 @zext_subw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind define i32 @aext_sllw_aext_aext(i32 %a, i32 %b) nounwind { ; RV64I-LABEL: aext_sllw_aext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: ret %1 = shl i32 %a, %b ret i32 %1 @@ -555,7 +555,7 @@ define i32 @aext_sllw_aext_aext(i32 %a, i32 %b) nounwind { define i32 @aext_sllw_aext_sext(i32 %a, i32 signext %b) nounwind { ; RV64I-LABEL: aext_sllw_aext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: ret %1 = shl i32 %a, %b ret i32 %1 @@ -564,7 +564,7 @@ define i32 @aext_sllw_aext_sext(i32 %a, i32 signext %b) nounwind { define i32 @aext_sllw_aext_zext(i32 %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: aext_sllw_aext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: ret %1 = shl i32 %a, %b ret i32 %1 @@ -573,7 +573,7 @@ define i32 @aext_sllw_aext_zext(i32 %a, i32 zeroext %b) nounwind { define i32 @aext_sllw_sext_aext(i32 signext %a, i32 %b) nounwind { ; RV64I-LABEL: aext_sllw_sext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: ret %1 = shl i32 %a, %b ret i32 %1 @@ -582,7 +582,7 @@ define i32 @aext_sllw_sext_aext(i32 signext %a, i32 %b) nounwind { define i32 @aext_sllw_sext_sext(i32 signext %a, i32 signext %b) nounwind { ; RV64I-LABEL: aext_sllw_sext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: ret %1 = shl i32 %a, %b ret i32 %1 @@ -591,7 +591,7 @@ define i32 @aext_sllw_sext_sext(i32 signext %a, i32 signext %b) nounwind { define i32 @aext_sllw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: aext_sllw_sext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: ret %1 = shl i32 %a, %b ret i32 %1 @@ -600,7 +600,7 @@ define i32 @aext_sllw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind { define i32 @aext_sllw_zext_aext(i32 zeroext %a, i32 %b) nounwind { ; RV64I-LABEL: aext_sllw_zext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: ret %1 = shl i32 %a, %b ret i32 %1 @@ -609,7 +609,7 @@ define i32 @aext_sllw_zext_aext(i32 zeroext %a, i32 %b) nounwind { define i32 @aext_sllw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind { ; RV64I-LABEL: aext_sllw_zext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: ret %1 = shl i32 %a, %b ret i32 %1 @@ -618,19 +618,16 @@ define i32 @aext_sllw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind { define i32 @aext_sllw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: aext_sllw_zext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: ret %1 = shl i32 %a, %b ret i32 %1 } -; TODO: Select sllw for all cases witha signext result. - define signext i32 @sext_sllw_aext_aext(i32 %a, i32 %b) nounwind { ; RV64I-LABEL: sext_sllw_aext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 -; RV64I-NEXT: sext.w a0, a0 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: ret %1 = shl i32 %a, %b ret i32 %1 @@ -639,8 +636,7 @@ define signext i32 @sext_sllw_aext_aext(i32 %a, i32 %b) nounwind { define signext i32 @sext_sllw_aext_sext(i32 %a, i32 signext %b) nounwind { ; RV64I-LABEL: sext_sllw_aext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 -; RV64I-NEXT: sext.w a0, a0 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: ret %1 = shl i32 %a, %b ret i32 %1 @@ -649,8 +645,7 @@ define signext i32 @sext_sllw_aext_sext(i32 %a, i32 signext %b) nounwind { define signext i32 @sext_sllw_aext_zext(i32 %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: sext_sllw_aext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 -; RV64I-NEXT: sext.w a0, a0 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: ret %1 = shl i32 %a, %b ret i32 %1 @@ -659,8 +654,7 @@ define signext i32 @sext_sllw_aext_zext(i32 %a, i32 zeroext %b) nounwind { define signext i32 @sext_sllw_sext_aext(i32 signext %a, i32 %b) nounwind { ; RV64I-LABEL: sext_sllw_sext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 -; RV64I-NEXT: sext.w a0, a0 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: ret %1 = shl i32 %a, %b ret i32 %1 @@ -669,8 +663,7 @@ define signext i32 @sext_sllw_sext_aext(i32 signext %a, i32 %b) nounwind { define signext i32 @sext_sllw_sext_sext(i32 signext %a, i32 signext %b) nounwind { ; RV64I-LABEL: sext_sllw_sext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 -; RV64I-NEXT: sext.w a0, a0 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: ret %1 = shl i32 %a, %b ret i32 %1 @@ -679,8 +672,7 @@ define signext i32 @sext_sllw_sext_sext(i32 signext %a, i32 signext %b) nounwind define signext i32 @sext_sllw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: sext_sllw_sext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 -; RV64I-NEXT: sext.w a0, a0 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: ret %1 = shl i32 %a, %b ret i32 %1 @@ -689,8 +681,7 @@ define signext i32 @sext_sllw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind define signext i32 @sext_sllw_zext_aext(i32 zeroext %a, i32 %b) nounwind { ; RV64I-LABEL: sext_sllw_zext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 -; RV64I-NEXT: sext.w a0, a0 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: ret %1 = shl i32 %a, %b ret i32 %1 @@ -699,8 +690,7 @@ define signext i32 @sext_sllw_zext_aext(i32 zeroext %a, i32 %b) nounwind { define signext i32 @sext_sllw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind { ; RV64I-LABEL: sext_sllw_zext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 -; RV64I-NEXT: sext.w a0, a0 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: ret %1 = shl i32 %a, %b ret i32 %1 @@ -709,8 +699,7 @@ define signext i32 @sext_sllw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind define signext i32 @sext_sllw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: sext_sllw_zext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 -; RV64I-NEXT: sext.w a0, a0 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: ret %1 = shl i32 %a, %b ret i32 %1 @@ -721,7 +710,7 @@ define signext i32 @sext_sllw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind define zeroext i32 @zext_sllw_aext_aext(i32 %a, i32 %b) nounwind { ; RV64I-LABEL: zext_sllw_aext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -732,7 +721,7 @@ define zeroext i32 @zext_sllw_aext_aext(i32 %a, i32 %b) nounwind { define zeroext i32 @zext_sllw_aext_sext(i32 %a, i32 signext %b) nounwind { ; RV64I-LABEL: zext_sllw_aext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -743,7 +732,7 @@ define zeroext i32 @zext_sllw_aext_sext(i32 %a, i32 signext %b) nounwind { define zeroext i32 @zext_sllw_aext_zext(i32 %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: zext_sllw_aext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -754,7 +743,7 @@ define zeroext i32 @zext_sllw_aext_zext(i32 %a, i32 zeroext %b) nounwind { define zeroext i32 @zext_sllw_sext_aext(i32 signext %a, i32 %b) nounwind { ; RV64I-LABEL: zext_sllw_sext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -765,7 +754,7 @@ define zeroext i32 @zext_sllw_sext_aext(i32 signext %a, i32 %b) nounwind { define zeroext i32 @zext_sllw_sext_sext(i32 signext %a, i32 signext %b) nounwind { ; RV64I-LABEL: zext_sllw_sext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -776,7 +765,7 @@ define zeroext i32 @zext_sllw_sext_sext(i32 signext %a, i32 signext %b) nounwind define zeroext i32 @zext_sllw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: zext_sllw_sext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -787,7 +776,7 @@ define zeroext i32 @zext_sllw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind define zeroext i32 @zext_sllw_zext_aext(i32 zeroext %a, i32 %b) nounwind { ; RV64I-LABEL: zext_sllw_zext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -798,7 +787,7 @@ define zeroext i32 @zext_sllw_zext_aext(i32 zeroext %a, i32 %b) nounwind { define zeroext i32 @zext_sllw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind { ; RV64I-LABEL: zext_sllw_zext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -809,7 +798,7 @@ define zeroext i32 @zext_sllw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind define zeroext i32 @zext_sllw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: zext_sllw_zext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: sll a0, a0, a1 +; RV64I-NEXT: sllw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -817,14 +806,10 @@ define zeroext i32 @zext_sllw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind ret i32 %1 } -; TODO: srlw should be selected for 32-bit lshr with variable arguments. - define i32 @aext_srlw_aext_aext(i32 %a, i32 %b) nounwind { ; RV64I-LABEL: aext_srlw_aext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: srli a0, a0, 32 -; RV64I-NEXT: srl a0, a0, a1 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: ret %1 = lshr i32 %a, %b ret i32 %1 @@ -833,9 +818,7 @@ define i32 @aext_srlw_aext_aext(i32 %a, i32 %b) nounwind { define i32 @aext_srlw_aext_sext(i32 %a, i32 signext %b) nounwind { ; RV64I-LABEL: aext_srlw_aext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: srli a0, a0, 32 -; RV64I-NEXT: srl a0, a0, a1 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: ret %1 = lshr i32 %a, %b ret i32 %1 @@ -844,9 +827,7 @@ define i32 @aext_srlw_aext_sext(i32 %a, i32 signext %b) nounwind { define i32 @aext_srlw_aext_zext(i32 %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: aext_srlw_aext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: srli a0, a0, 32 -; RV64I-NEXT: srl a0, a0, a1 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: ret %1 = lshr i32 %a, %b ret i32 %1 @@ -855,9 +836,7 @@ define i32 @aext_srlw_aext_zext(i32 %a, i32 zeroext %b) nounwind { define i32 @aext_srlw_sext_aext(i32 signext %a, i32 %b) nounwind { ; RV64I-LABEL: aext_srlw_sext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: srli a0, a0, 32 -; RV64I-NEXT: srl a0, a0, a1 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: ret %1 = lshr i32 %a, %b ret i32 %1 @@ -866,9 +845,7 @@ define i32 @aext_srlw_sext_aext(i32 signext %a, i32 %b) nounwind { define i32 @aext_srlw_sext_sext(i32 signext %a, i32 signext %b) nounwind { ; RV64I-LABEL: aext_srlw_sext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: srli a0, a0, 32 -; RV64I-NEXT: srl a0, a0, a1 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: ret %1 = lshr i32 %a, %b ret i32 %1 @@ -877,9 +854,7 @@ define i32 @aext_srlw_sext_sext(i32 signext %a, i32 signext %b) nounwind { define i32 @aext_srlw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: aext_srlw_sext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: srli a0, a0, 32 -; RV64I-NEXT: srl a0, a0, a1 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: ret %1 = lshr i32 %a, %b ret i32 %1 @@ -888,7 +863,7 @@ define i32 @aext_srlw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind { define i32 @aext_srlw_zext_aext(i32 zeroext %a, i32 %b) nounwind { ; RV64I-LABEL: aext_srlw_zext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: srl a0, a0, a1 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: ret %1 = lshr i32 %a, %b ret i32 %1 @@ -897,7 +872,7 @@ define i32 @aext_srlw_zext_aext(i32 zeroext %a, i32 %b) nounwind { define i32 @aext_srlw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind { ; RV64I-LABEL: aext_srlw_zext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: srl a0, a0, a1 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: ret %1 = lshr i32 %a, %b ret i32 %1 @@ -906,7 +881,7 @@ define i32 @aext_srlw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind { define i32 @aext_srlw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: aext_srlw_zext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: srl a0, a0, a1 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: ret %1 = lshr i32 %a, %b ret i32 %1 @@ -915,10 +890,7 @@ define i32 @aext_srlw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind { define signext i32 @sext_srlw_aext_aext(i32 %a, i32 %b) nounwind { ; RV64I-LABEL: sext_srlw_aext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: srli a0, a0, 32 -; RV64I-NEXT: srl a0, a0, a1 -; RV64I-NEXT: sext.w a0, a0 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: ret %1 = lshr i32 %a, %b ret i32 %1 @@ -927,10 +899,7 @@ define signext i32 @sext_srlw_aext_aext(i32 %a, i32 %b) nounwind { define signext i32 @sext_srlw_aext_sext(i32 %a, i32 signext %b) nounwind { ; RV64I-LABEL: sext_srlw_aext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: srli a0, a0, 32 -; RV64I-NEXT: srl a0, a0, a1 -; RV64I-NEXT: sext.w a0, a0 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: ret %1 = lshr i32 %a, %b ret i32 %1 @@ -939,10 +908,7 @@ define signext i32 @sext_srlw_aext_sext(i32 %a, i32 signext %b) nounwind { define signext i32 @sext_srlw_aext_zext(i32 %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: sext_srlw_aext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: srli a0, a0, 32 -; RV64I-NEXT: srl a0, a0, a1 -; RV64I-NEXT: sext.w a0, a0 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: ret %1 = lshr i32 %a, %b ret i32 %1 @@ -951,10 +917,7 @@ define signext i32 @sext_srlw_aext_zext(i32 %a, i32 zeroext %b) nounwind { define signext i32 @sext_srlw_sext_aext(i32 signext %a, i32 %b) nounwind { ; RV64I-LABEL: sext_srlw_sext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: srli a0, a0, 32 -; RV64I-NEXT: srl a0, a0, a1 -; RV64I-NEXT: sext.w a0, a0 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: ret %1 = lshr i32 %a, %b ret i32 %1 @@ -963,10 +926,7 @@ define signext i32 @sext_srlw_sext_aext(i32 signext %a, i32 %b) nounwind { define signext i32 @sext_srlw_sext_sext(i32 signext %a, i32 signext %b) nounwind { ; RV64I-LABEL: sext_srlw_sext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: srli a0, a0, 32 -; RV64I-NEXT: srl a0, a0, a1 -; RV64I-NEXT: sext.w a0, a0 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: ret %1 = lshr i32 %a, %b ret i32 %1 @@ -975,10 +935,7 @@ define signext i32 @sext_srlw_sext_sext(i32 signext %a, i32 signext %b) nounwind define signext i32 @sext_srlw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: sext_srlw_sext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: srli a0, a0, 32 -; RV64I-NEXT: srl a0, a0, a1 -; RV64I-NEXT: sext.w a0, a0 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: ret %1 = lshr i32 %a, %b ret i32 %1 @@ -987,8 +944,7 @@ define signext i32 @sext_srlw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind define signext i32 @sext_srlw_zext_aext(i32 zeroext %a, i32 %b) nounwind { ; RV64I-LABEL: sext_srlw_zext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: srl a0, a0, a1 -; RV64I-NEXT: sext.w a0, a0 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: ret %1 = lshr i32 %a, %b ret i32 %1 @@ -997,8 +953,7 @@ define signext i32 @sext_srlw_zext_aext(i32 zeroext %a, i32 %b) nounwind { define signext i32 @sext_srlw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind { ; RV64I-LABEL: sext_srlw_zext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: srl a0, a0, a1 -; RV64I-NEXT: sext.w a0, a0 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: ret %1 = lshr i32 %a, %b ret i32 %1 @@ -1007,8 +962,7 @@ define signext i32 @sext_srlw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind define signext i32 @sext_srlw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: sext_srlw_zext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: srl a0, a0, a1 -; RV64I-NEXT: sext.w a0, a0 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: ret %1 = lshr i32 %a, %b ret i32 %1 @@ -1017,9 +971,7 @@ define signext i32 @sext_srlw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind define zeroext i32 @zext_srlw_aext_aext(i32 %a, i32 %b) nounwind { ; RV64I-LABEL: zext_srlw_aext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: srli a0, a0, 32 -; RV64I-NEXT: srl a0, a0, a1 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -1030,9 +982,7 @@ define zeroext i32 @zext_srlw_aext_aext(i32 %a, i32 %b) nounwind { define zeroext i32 @zext_srlw_aext_sext(i32 %a, i32 signext %b) nounwind { ; RV64I-LABEL: zext_srlw_aext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: srli a0, a0, 32 -; RV64I-NEXT: srl a0, a0, a1 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -1043,9 +993,7 @@ define zeroext i32 @zext_srlw_aext_sext(i32 %a, i32 signext %b) nounwind { define zeroext i32 @zext_srlw_aext_zext(i32 %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: zext_srlw_aext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: srli a0, a0, 32 -; RV64I-NEXT: srl a0, a0, a1 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -1056,9 +1004,7 @@ define zeroext i32 @zext_srlw_aext_zext(i32 %a, i32 zeroext %b) nounwind { define zeroext i32 @zext_srlw_sext_aext(i32 signext %a, i32 %b) nounwind { ; RV64I-LABEL: zext_srlw_sext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: srli a0, a0, 32 -; RV64I-NEXT: srl a0, a0, a1 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -1069,9 +1015,7 @@ define zeroext i32 @zext_srlw_sext_aext(i32 signext %a, i32 %b) nounwind { define zeroext i32 @zext_srlw_sext_sext(i32 signext %a, i32 signext %b) nounwind { ; RV64I-LABEL: zext_srlw_sext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: srli a0, a0, 32 -; RV64I-NEXT: srl a0, a0, a1 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -1082,9 +1026,7 @@ define zeroext i32 @zext_srlw_sext_sext(i32 signext %a, i32 signext %b) nounwind define zeroext i32 @zext_srlw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: zext_srlw_sext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: srli a0, a0, 32 -; RV64I-NEXT: srl a0, a0, a1 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -1095,7 +1037,7 @@ define zeroext i32 @zext_srlw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind define zeroext i32 @zext_srlw_zext_aext(i32 zeroext %a, i32 %b) nounwind { ; RV64I-LABEL: zext_srlw_zext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: srl a0, a0, a1 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -1106,7 +1048,7 @@ define zeroext i32 @zext_srlw_zext_aext(i32 zeroext %a, i32 %b) nounwind { define zeroext i32 @zext_srlw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind { ; RV64I-LABEL: zext_srlw_zext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: srl a0, a0, a1 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -1117,7 +1059,7 @@ define zeroext i32 @zext_srlw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind define zeroext i32 @zext_srlw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: zext_srlw_zext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: srl a0, a0, a1 +; RV64I-NEXT: srlw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -1125,14 +1067,10 @@ define zeroext i32 @zext_srlw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind ret i32 %1 } -; TODO: sraw should be selected if the first operand is not sign-extended. If the -; first operand is sign-extended, sra is equivalent for the test cases below. - define i32 @aext_sraw_aext_aext(i32 %a, i32 %b) nounwind { ; RV64I-LABEL: aext_sraw_aext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: sext.w a0, a0 -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: ret %1 = ashr i32 %a, %b ret i32 %1 @@ -1141,8 +1079,7 @@ define i32 @aext_sraw_aext_aext(i32 %a, i32 %b) nounwind { define i32 @aext_sraw_aext_sext(i32 %a, i32 signext %b) nounwind { ; RV64I-LABEL: aext_sraw_aext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: sext.w a0, a0 -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: ret %1 = ashr i32 %a, %b ret i32 %1 @@ -1151,8 +1088,7 @@ define i32 @aext_sraw_aext_sext(i32 %a, i32 signext %b) nounwind { define i32 @aext_sraw_aext_zext(i32 %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: aext_sraw_aext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: sext.w a0, a0 -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: ret %1 = ashr i32 %a, %b ret i32 %1 @@ -1161,7 +1097,7 @@ define i32 @aext_sraw_aext_zext(i32 %a, i32 zeroext %b) nounwind { define i32 @aext_sraw_sext_aext(i32 signext %a, i32 %b) nounwind { ; RV64I-LABEL: aext_sraw_sext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: ret %1 = ashr i32 %a, %b ret i32 %1 @@ -1170,7 +1106,7 @@ define i32 @aext_sraw_sext_aext(i32 signext %a, i32 %b) nounwind { define i32 @aext_sraw_sext_sext(i32 signext %a, i32 signext %b) nounwind { ; RV64I-LABEL: aext_sraw_sext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: ret %1 = ashr i32 %a, %b ret i32 %1 @@ -1179,7 +1115,7 @@ define i32 @aext_sraw_sext_sext(i32 signext %a, i32 signext %b) nounwind { define i32 @aext_sraw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: aext_sraw_sext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: ret %1 = ashr i32 %a, %b ret i32 %1 @@ -1188,8 +1124,7 @@ define i32 @aext_sraw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind { define i32 @aext_sraw_zext_aext(i32 zeroext %a, i32 %b) nounwind { ; RV64I-LABEL: aext_sraw_zext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: sext.w a0, a0 -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: ret %1 = ashr i32 %a, %b ret i32 %1 @@ -1198,8 +1133,7 @@ define i32 @aext_sraw_zext_aext(i32 zeroext %a, i32 %b) nounwind { define i32 @aext_sraw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind { ; RV64I-LABEL: aext_sraw_zext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: sext.w a0, a0 -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: ret %1 = ashr i32 %a, %b ret i32 %1 @@ -1208,8 +1142,7 @@ define i32 @aext_sraw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind { define i32 @aext_sraw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: aext_sraw_zext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: sext.w a0, a0 -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: ret %1 = ashr i32 %a, %b ret i32 %1 @@ -1218,8 +1151,7 @@ define i32 @aext_sraw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind { define signext i32 @sext_sraw_aext_aext(i32 %a, i32 %b) nounwind { ; RV64I-LABEL: sext_sraw_aext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: sext.w a0, a0 -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: ret %1 = ashr i32 %a, %b ret i32 %1 @@ -1228,8 +1160,7 @@ define signext i32 @sext_sraw_aext_aext(i32 %a, i32 %b) nounwind { define signext i32 @sext_sraw_aext_sext(i32 %a, i32 signext %b) nounwind { ; RV64I-LABEL: sext_sraw_aext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: sext.w a0, a0 -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: ret %1 = ashr i32 %a, %b ret i32 %1 @@ -1238,8 +1169,7 @@ define signext i32 @sext_sraw_aext_sext(i32 %a, i32 signext %b) nounwind { define signext i32 @sext_sraw_aext_zext(i32 %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: sext_sraw_aext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: sext.w a0, a0 -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: ret %1 = ashr i32 %a, %b ret i32 %1 @@ -1248,7 +1178,7 @@ define signext i32 @sext_sraw_aext_zext(i32 %a, i32 zeroext %b) nounwind { define signext i32 @sext_sraw_sext_aext(i32 signext %a, i32 %b) nounwind { ; RV64I-LABEL: sext_sraw_sext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: ret %1 = ashr i32 %a, %b ret i32 %1 @@ -1257,7 +1187,7 @@ define signext i32 @sext_sraw_sext_aext(i32 signext %a, i32 %b) nounwind { define signext i32 @sext_sraw_sext_sext(i32 signext %a, i32 signext %b) nounwind { ; RV64I-LABEL: sext_sraw_sext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: ret %1 = ashr i32 %a, %b ret i32 %1 @@ -1266,7 +1196,7 @@ define signext i32 @sext_sraw_sext_sext(i32 signext %a, i32 signext %b) nounwind define signext i32 @sext_sraw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: sext_sraw_sext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: ret %1 = ashr i32 %a, %b ret i32 %1 @@ -1275,8 +1205,7 @@ define signext i32 @sext_sraw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind define signext i32 @sext_sraw_zext_aext(i32 zeroext %a, i32 %b) nounwind { ; RV64I-LABEL: sext_sraw_zext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: sext.w a0, a0 -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: ret %1 = ashr i32 %a, %b ret i32 %1 @@ -1285,8 +1214,7 @@ define signext i32 @sext_sraw_zext_aext(i32 zeroext %a, i32 %b) nounwind { define signext i32 @sext_sraw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind { ; RV64I-LABEL: sext_sraw_zext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: sext.w a0, a0 -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: ret %1 = ashr i32 %a, %b ret i32 %1 @@ -1295,8 +1223,7 @@ define signext i32 @sext_sraw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind define signext i32 @sext_sraw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: sext_sraw_zext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: sext.w a0, a0 -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: ret %1 = ashr i32 %a, %b ret i32 %1 @@ -1305,8 +1232,7 @@ define signext i32 @sext_sraw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind define zeroext i32 @zext_sraw_aext_aext(i32 %a, i32 %b) nounwind { ; RV64I-LABEL: zext_sraw_aext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: sext.w a0, a0 -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -1317,8 +1243,7 @@ define zeroext i32 @zext_sraw_aext_aext(i32 %a, i32 %b) nounwind { define zeroext i32 @zext_sraw_aext_sext(i32 %a, i32 signext %b) nounwind { ; RV64I-LABEL: zext_sraw_aext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: sext.w a0, a0 -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -1329,8 +1254,7 @@ define zeroext i32 @zext_sraw_aext_sext(i32 %a, i32 signext %b) nounwind { define zeroext i32 @zext_sraw_aext_zext(i32 %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: zext_sraw_aext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: sext.w a0, a0 -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -1341,7 +1265,7 @@ define zeroext i32 @zext_sraw_aext_zext(i32 %a, i32 zeroext %b) nounwind { define zeroext i32 @zext_sraw_sext_aext(i32 signext %a, i32 %b) nounwind { ; RV64I-LABEL: zext_sraw_sext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -1352,7 +1276,7 @@ define zeroext i32 @zext_sraw_sext_aext(i32 signext %a, i32 %b) nounwind { define zeroext i32 @zext_sraw_sext_sext(i32 signext %a, i32 signext %b) nounwind { ; RV64I-LABEL: zext_sraw_sext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -1363,7 +1287,7 @@ define zeroext i32 @zext_sraw_sext_sext(i32 signext %a, i32 signext %b) nounwind define zeroext i32 @zext_sraw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: zext_sraw_sext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -1374,8 +1298,7 @@ define zeroext i32 @zext_sraw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind define zeroext i32 @zext_sraw_zext_aext(i32 zeroext %a, i32 %b) nounwind { ; RV64I-LABEL: zext_sraw_zext_aext: ; RV64I: # %bb.0: -; RV64I-NEXT: sext.w a0, a0 -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -1386,8 +1309,7 @@ define zeroext i32 @zext_sraw_zext_aext(i32 zeroext %a, i32 %b) nounwind { define zeroext i32 @zext_sraw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind { ; RV64I-LABEL: zext_sraw_zext_sext: ; RV64I: # %bb.0: -; RV64I-NEXT: sext.w a0, a0 -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret @@ -1398,8 +1320,7 @@ define zeroext i32 @zext_sraw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind define zeroext i32 @zext_sraw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind { ; RV64I-LABEL: zext_sraw_zext_zext: ; RV64I: # %bb.0: -; RV64I-NEXT: sext.w a0, a0 -; RV64I-NEXT: sra a0, a0, a1 +; RV64I-NEXT: sraw a0, a0, a1 ; RV64I-NEXT: slli a0, a0, 32 ; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret -- 2.7.4