diff options
author | NAKAMURA Takumi <geek4civic@gmail.com> | 2025-01-09 18:43:11 +0900 |
---|---|---|
committer | NAKAMURA Takumi <geek4civic@gmail.com> | 2025-01-09 18:43:11 +0900 |
commit | 0e1a753549b29ff1f5a190aca83b803a33b51628 (patch) | |
tree | e5578f8810c65711304128d0c8add7fa1f77b9d8 /llvm/lib/Target/RISCV/RISCVISelLowering.cpp | |
parent | 3c6252260ee11e3a453076b4d96ffffe20d49998 (diff) | |
parent | bdcf47e4bcb92889665825654bb80a8bbe30379e (diff) | |
download | llvm-users/chapuni/cov/single/if.zip llvm-users/chapuni/cov/single/if.tar.gz llvm-users/chapuni/cov/single/if.tar.bz2 |
Merge branch 'users/chapuni/cov/single/base' into users/chapuni/cov/single/ifusers/chapuni/cov/single/if
Conflicts:
clang/lib/CodeGen/CoverageMappingGen.cpp
Diffstat (limited to 'llvm/lib/Target/RISCV/RISCVISelLowering.cpp')
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 137 |
1 files changed, 65 insertions, 72 deletions
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index cda64ae..6c58989 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -5104,6 +5104,7 @@ static SDValue lowerShuffleViaVRegSplitting(ShuffleVectorSDNode *SVN, SDValue V1 = SVN->getOperand(0); SDValue V2 = SVN->getOperand(1); ArrayRef<int> Mask = SVN->getMask(); + unsigned NumElts = VT.getVectorNumElements(); // If we don't know exact data layout, not much we can do. If this // is already m1 or smaller, no point in splitting further. @@ -5120,70 +5121,58 @@ static SDValue lowerShuffleViaVRegSplitting(ShuffleVectorSDNode *SVN, MVT ElemVT = VT.getVectorElementType(); unsigned ElemsPerVReg = *VLen / ElemVT.getFixedSizeInBits(); + unsigned VRegsPerSrc = NumElts / ElemsPerVReg; + + SmallVector<std::pair<int, SmallVector<int>>> + OutMasks(VRegsPerSrc, {-1, {}}); + + // Check if our mask can be done as a 1-to-1 mapping from source + // to destination registers in the group without needing to + // write each destination more than once. + for (unsigned DstIdx = 0; DstIdx < Mask.size(); DstIdx++) { + int DstVecIdx = DstIdx / ElemsPerVReg; + int DstSubIdx = DstIdx % ElemsPerVReg; + int SrcIdx = Mask[DstIdx]; + if (SrcIdx < 0 || (unsigned)SrcIdx >= 2 * NumElts) + continue; + int SrcVecIdx = SrcIdx / ElemsPerVReg; + int SrcSubIdx = SrcIdx % ElemsPerVReg; + if (OutMasks[DstVecIdx].first == -1) + OutMasks[DstVecIdx].first = SrcVecIdx; + if (OutMasks[DstVecIdx].first != SrcVecIdx) + // Note: This case could easily be handled by keeping track of a chain + // of source values and generating two element shuffles below. This is + // less an implementation question, and more a profitability one. + return SDValue(); + + OutMasks[DstVecIdx].second.resize(ElemsPerVReg, -1); + OutMasks[DstVecIdx].second[DstSubIdx] = SrcSubIdx; + } EVT ContainerVT = getContainerForFixedLengthVector(DAG, VT, Subtarget); MVT OneRegVT = MVT::getVectorVT(ElemVT, ElemsPerVReg); MVT M1VT = getContainerForFixedLengthVector(DAG, OneRegVT, Subtarget); assert(M1VT == getLMUL1VT(M1VT)); unsigned NumOpElts = M1VT.getVectorMinNumElements(); - unsigned NormalizedVF = ContainerVT.getVectorMinNumElements(); - unsigned NumOfSrcRegs = NormalizedVF / NumOpElts; - unsigned NumOfDestRegs = NormalizedVF / NumOpElts; + SDValue Vec = DAG.getUNDEF(ContainerVT); // The following semantically builds up a fixed length concat_vector // of the component shuffle_vectors. We eagerly lower to scalable here // to avoid DAG combining it back to a large shuffle_vector again. V1 = convertToScalableVector(ContainerVT, V1, DAG, Subtarget); V2 = convertToScalableVector(ContainerVT, V2, DAG, Subtarget); - SmallVector<SDValue> SubRegs(NumOfDestRegs); - unsigned RegCnt = 0; - unsigned PrevCnt = 0; - processShuffleMasks( - Mask, NumOfSrcRegs, NumOfDestRegs, NumOfDestRegs, - [&]() { - PrevCnt = RegCnt; - ++RegCnt; - }, - [&, &DAG = DAG](ArrayRef<int> SrcSubMask, unsigned SrcVecIdx, - unsigned DstVecIdx) { - SDValue SrcVec = SrcVecIdx >= NumOfSrcRegs ? V2 : V1; - unsigned ExtractIdx = (SrcVecIdx % NumOfSrcRegs) * NumOpElts; - SDValue SubVec = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, M1VT, SrcVec, - DAG.getVectorIdxConstant(ExtractIdx, DL)); - SubVec = convertFromScalableVector(OneRegVT, SubVec, DAG, Subtarget); - SubVec = DAG.getVectorShuffle(OneRegVT, DL, SubVec, SubVec, SrcSubMask); - SubRegs[RegCnt] = convertToScalableVector(M1VT, SubVec, DAG, Subtarget); - PrevCnt = RegCnt; - ++RegCnt; - }, - [&, &DAG = DAG](ArrayRef<int> SrcSubMask, unsigned Idx1, unsigned Idx2) { - if (PrevCnt + 1 == RegCnt) - ++RegCnt; - SDValue SubVec1 = SubRegs[PrevCnt + 1]; - if (!SubVec1) { - SDValue SrcVec = Idx1 >= NumOfSrcRegs ? V2 : V1; - unsigned ExtractIdx = (Idx1 % NumOfSrcRegs) * NumOpElts; - SubVec1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, M1VT, SrcVec, - DAG.getVectorIdxConstant(ExtractIdx, DL)); - } - SubVec1 = convertFromScalableVector(OneRegVT, SubVec1, DAG, Subtarget); - SDValue SrcVec = Idx2 >= NumOfSrcRegs ? V2 : V1; - unsigned ExtractIdx = (Idx2 % NumOfSrcRegs) * NumOpElts; - SDValue SubVec2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, M1VT, SrcVec, - DAG.getVectorIdxConstant(ExtractIdx, DL)); - SubVec2 = convertFromScalableVector(OneRegVT, SubVec2, DAG, Subtarget); - SubVec1 = - DAG.getVectorShuffle(OneRegVT, DL, SubVec1, SubVec2, SrcSubMask); - SubVec1 = convertToScalableVector(M1VT, SubVec1, DAG, Subtarget); - SubRegs[PrevCnt + 1] = SubVec1; - }); - assert(RegCnt == NumOfDestRegs && "Whole vector must be processed"); - SDValue Vec = DAG.getUNDEF(ContainerVT); - for (auto [I, V] : enumerate(SubRegs)) { - if (!V) + for (unsigned DstVecIdx = 0 ; DstVecIdx < OutMasks.size(); DstVecIdx++) { + auto &[SrcVecIdx, SrcSubMask] = OutMasks[DstVecIdx]; + if (SrcVecIdx == -1) continue; - unsigned InsertIdx = I * NumOpElts; - - Vec = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, ContainerVT, Vec, V, + unsigned ExtractIdx = (SrcVecIdx % VRegsPerSrc) * NumOpElts; + SDValue SrcVec = (unsigned)SrcVecIdx >= VRegsPerSrc ? V2 : V1; + SDValue SubVec = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, M1VT, SrcVec, + DAG.getVectorIdxConstant(ExtractIdx, DL)); + SubVec = convertFromScalableVector(OneRegVT, SubVec, DAG, Subtarget); + SubVec = DAG.getVectorShuffle(OneRegVT, DL, SubVec, SubVec, SrcSubMask); + SubVec = convertToScalableVector(M1VT, SubVec, DAG, Subtarget); + unsigned InsertIdx = DstVecIdx * NumOpElts; + Vec = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, ContainerVT, Vec, SubVec, DAG.getVectorIdxConstant(InsertIdx, DL)); } return convertFromScalableVector(VT, Vec, DAG, Subtarget); @@ -10165,7 +10154,10 @@ SDValue RISCVTargetLowering::lowerVectorMaskVecReduction(SDValue Op, case ISD::VP_REDUCE_AND: { // vcpop ~x == 0 SDValue TrueMask = DAG.getNode(RISCVISD::VMSET_VL, DL, ContainerVT, VL); - Vec = DAG.getNode(RISCVISD::VMXOR_VL, DL, ContainerVT, Vec, TrueMask, VL); + if (IsVP || VecVT.isFixedLengthVector()) + Vec = DAG.getNode(RISCVISD::VMXOR_VL, DL, ContainerVT, Vec, TrueMask, VL); + else + Vec = DAG.getNode(ISD::XOR, DL, ContainerVT, Vec, TrueMask); Vec = DAG.getNode(RISCVISD::VCPOP_VL, DL, XLenVT, Vec, Mask, VL); CC = ISD::SETEQ; break; @@ -12674,8 +12666,7 @@ SDValue RISCVTargetLowering::lowerGET_ROUNDING(SDValue Op, const MVT XLenVT = Subtarget.getXLenVT(); SDLoc DL(Op); SDValue Chain = Op->getOperand(0); - SDValue SysRegNo = DAG.getTargetConstant( - RISCVSysReg::lookupSysRegByName("FRM")->Encoding, DL, XLenVT); + SDValue SysRegNo = DAG.getTargetConstant(RISCVSysReg::frm, DL, XLenVT); SDVTList VTs = DAG.getVTList(XLenVT, MVT::Other); SDValue RM = DAG.getNode(RISCVISD::READ_CSR, DL, VTs, Chain, SysRegNo); @@ -12706,8 +12697,7 @@ SDValue RISCVTargetLowering::lowerSET_ROUNDING(SDValue Op, SDLoc DL(Op); SDValue Chain = Op->getOperand(0); SDValue RMValue = Op->getOperand(1); - SDValue SysRegNo = DAG.getTargetConstant( - RISCVSysReg::lookupSysRegByName("FRM")->Encoding, DL, XLenVT); + SDValue SysRegNo = DAG.getTargetConstant(RISCVSysReg::frm, DL, XLenVT); // Encoding used for rounding mode in RISC-V differs from that used in // FLT_ROUNDS. To convert it the C rounding mode is used as an index in @@ -12910,15 +12900,11 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N, SDValue LoCounter, HiCounter; MVT XLenVT = Subtarget.getXLenVT(); if (N->getOpcode() == ISD::READCYCLECOUNTER) { - LoCounter = DAG.getTargetConstant( - RISCVSysReg::lookupSysRegByName("CYCLE")->Encoding, DL, XLenVT); - HiCounter = DAG.getTargetConstant( - RISCVSysReg::lookupSysRegByName("CYCLEH")->Encoding, DL, XLenVT); + LoCounter = DAG.getTargetConstant(RISCVSysReg::cycle, DL, XLenVT); + HiCounter = DAG.getTargetConstant(RISCVSysReg::cycleh, DL, XLenVT); } else { - LoCounter = DAG.getTargetConstant( - RISCVSysReg::lookupSysRegByName("TIME")->Encoding, DL, XLenVT); - HiCounter = DAG.getTargetConstant( - RISCVSysReg::lookupSysRegByName("TIMEH")->Encoding, DL, XLenVT); + LoCounter = DAG.getTargetConstant(RISCVSysReg::time, DL, XLenVT); + HiCounter = DAG.getTargetConstant(RISCVSysReg::timeh, DL, XLenVT); } SDVTList VTs = DAG.getVTList(MVT::i32, MVT::i32, MVT::Other); SDValue RCW = DAG.getNode(RISCVISD::READ_COUNTER_WIDE, DL, VTs, @@ -18397,6 +18383,15 @@ bool RISCVTargetLowering::isDesirableToCommuteWithShift( auto *C1 = dyn_cast<ConstantSDNode>(N0->getOperand(1)); auto *C2 = dyn_cast<ConstantSDNode>(N->getOperand(1)); + + // Bail if we might break a sh{1,2,3}add pattern. + if (Subtarget.hasStdExtZba() && C2 && C2->getZExtValue() >= 1 && + C2->getZExtValue() <= 3 && N->hasOneUse() && + N->user_begin()->getOpcode() == ISD::ADD && + !isUsedByLdSt(*N->user_begin(), nullptr) && + !isa<ConstantSDNode>(N->user_begin()->getOperand(1))) + return false; + if (C1 && C2) { const APInt &C1Int = C1->getAPIntValue(); APInt ShiftedC1Int = C1Int << C2->getAPIntValue(); @@ -20278,13 +20273,11 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI, for (auto &Reg : RegsToPass) Ops.push_back(DAG.getRegister(Reg.first, Reg.second.getValueType())); - if (!IsTailCall) { - // Add a register mask operand representing the call-preserved registers. - const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo(); - const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv); - assert(Mask && "Missing call preserved mask for calling convention"); - Ops.push_back(DAG.getRegisterMask(Mask)); - } + // Add a register mask operand representing the call-preserved registers. + const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo(); + const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv); + assert(Mask && "Missing call preserved mask for calling convention"); + Ops.push_back(DAG.getRegisterMask(Mask)); // Glue the call to the argument copies, if any. if (Glue.getNode()) |