diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp | 150 |
1 files changed, 84 insertions, 66 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index 37bc8a65dc7c..fb046d519ac8 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -15,10 +15,13 @@ #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" #include "llvm/CodeGen/GlobalISel/CallLowering.h" #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" +#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h" #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" #include "llvm/CodeGen/GlobalISel/LostDebugLocObserver.h" #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" +#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" #include "llvm/CodeGen/GlobalISel/Utils.h" +#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/TargetFrameLowering.h" #include "llvm/CodeGen/TargetInstrInfo.h" @@ -1611,40 +1614,6 @@ LegalizerHelper::widenScalarMergeValues(MachineInstr &MI, unsigned TypeIdx, return Legalized; } -Register LegalizerHelper::widenWithUnmerge(LLT WideTy, Register OrigReg) { - Register WideReg = MRI.createGenericVirtualRegister(WideTy); - LLT OrigTy = MRI.getType(OrigReg); - LLT LCMTy = getLCMType(WideTy, OrigTy); - - const int NumMergeParts = LCMTy.getSizeInBits() / WideTy.getSizeInBits(); - const int NumUnmergeParts = LCMTy.getSizeInBits() / OrigTy.getSizeInBits(); - - Register UnmergeSrc = WideReg; - - // Create a merge to the LCM type, padding with undef - // %0:_(<3 x s32>) = G_FOO => <4 x s32> - // => - // %1:_(<4 x s32>) = G_FOO - // %2:_(<4 x s32>) = G_IMPLICIT_DEF - // %3:_(<12 x s32>) = G_CONCAT_VECTORS %1, %2, %2 - // %0:_(<3 x s32>), %4:_, %5:_, %6:_ = G_UNMERGE_VALUES %3 - if (NumMergeParts > 1) { - Register Undef = MIRBuilder.buildUndef(WideTy).getReg(0); - SmallVector<Register, 8> MergeParts(NumMergeParts, Undef); - MergeParts[0] = WideReg; - UnmergeSrc = MIRBuilder.buildMerge(LCMTy, MergeParts).getReg(0); - } - - // Unmerge to the original register and pad with dead defs. - SmallVector<Register, 8> UnmergeResults(NumUnmergeParts); - UnmergeResults[0] = OrigReg; - for (int I = 1; I != NumUnmergeParts; ++I) - UnmergeResults[I] = MRI.createGenericVirtualRegister(OrigTy); - - MIRBuilder.buildUnmerge(UnmergeResults, UnmergeSrc); - return WideReg; -} - LegalizerHelper::LegalizeResult LegalizerHelper::widenScalarUnmergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) { @@ -1867,9 +1836,6 @@ LegalizerHelper::widenScalarInsert(MachineInstr &MI, unsigned TypeIdx, LegalizerHelper::LegalizeResult LegalizerHelper::widenScalarAddSubOverflow(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) { - if (TypeIdx == 1) - return UnableToLegalize; // TODO - unsigned Opcode; unsigned ExtOpcode; Optional<Register> CarryIn = None; @@ -1914,6 +1880,18 @@ LegalizerHelper::widenScalarAddSubOverflow(MachineInstr &MI, unsigned TypeIdx, break; } + if (TypeIdx == 1) { + unsigned BoolExtOp = MIRBuilder.getBoolExtOp(WideTy.isVector(), false); + + Observer.changingInstr(MI); + widenScalarDst(MI, WideTy, 1); + if (CarryIn) + widenScalarSrc(MI, WideTy, 4, BoolExtOp); + + Observer.changedInstr(MI); + return Legalized; + } + auto LHSExt = MIRBuilder.buildInstr(ExtOpcode, {WideTy}, {MI.getOperand(2)}); auto RHSExt = MIRBuilder.buildInstr(ExtOpcode, {WideTy}, {MI.getOperand(3)}); // Do the arithmetic in the larger type. @@ -1985,8 +1963,12 @@ LegalizerHelper::widenScalarAddSubShlSat(MachineInstr &MI, unsigned TypeIdx, LegalizerHelper::LegalizeResult LegalizerHelper::widenScalarMulo(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) { - if (TypeIdx == 1) - return UnableToLegalize; + if (TypeIdx == 1) { + Observer.changingInstr(MI); + widenScalarDst(MI, WideTy, 1); + Observer.changedInstr(MI); + return Legalized; + } bool IsSigned = MI.getOpcode() == TargetOpcode::G_SMULO; Register Result = MI.getOperand(0).getReg(); @@ -2992,7 +2974,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerLoad(GAnyLoad &LoadMI) { if (isa<GSExtLoad>(LoadMI)) { auto NewLoad = MIRBuilder.buildLoad(LoadTy, PtrReg, *NewMMO); MIRBuilder.buildSExtInReg(LoadReg, NewLoad, MemSizeInBits); - } else if (isa<GZExtLoad>(LoadMI) || WideMemTy == DstTy) { + } else if (isa<GZExtLoad>(LoadMI) || WideMemTy == LoadTy) { auto NewLoad = MIRBuilder.buildLoad(LoadTy, PtrReg, *NewMMO); // The extra bits are guaranteed to be zero, since we stored them that // way. A zext load from Wide thus automatically gives zext from MemVT. @@ -3314,7 +3296,7 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) { Observer.changingInstr(MI); const auto &TII = MIRBuilder.getTII(); MI.setDesc(TII.get(TargetOpcode::G_MUL)); - MI.RemoveOperand(1); + MI.removeOperand(1); Observer.changedInstr(MI); auto HiPart = MIRBuilder.buildInstr(Opcode, {Ty}, {LHS, RHS}); @@ -4096,13 +4078,14 @@ LegalizerHelper::reduceLoadStoreWidth(GLoadStore &LdStMI, unsigned TypeIdx, // is a load, return the new registers in ValRegs. For a store, each elements // of ValRegs should be PartTy. Returns the next offset that needs to be // handled. + bool isBigEndian = MIRBuilder.getDataLayout().isBigEndian(); auto MMO = LdStMI.getMMO(); auto splitTypePieces = [=](LLT PartTy, SmallVectorImpl<Register> &ValRegs, - unsigned Offset) -> unsigned { + unsigned NumParts, unsigned Offset) -> unsigned { MachineFunction &MF = MIRBuilder.getMF(); unsigned PartSize = PartTy.getSizeInBits(); for (unsigned Idx = 0, E = NumParts; Idx != E && Offset < TotalSize; - Offset += PartSize, ++Idx) { + ++Idx) { unsigned ByteOffset = Offset / 8; Register NewAddrReg; @@ -4118,16 +4101,19 @@ LegalizerHelper::reduceLoadStoreWidth(GLoadStore &LdStMI, unsigned TypeIdx, } else { MIRBuilder.buildStore(ValRegs[Idx], NewAddrReg, *NewMMO); } + Offset = isBigEndian ? Offset - PartSize : Offset + PartSize; } return Offset; }; - unsigned HandledOffset = splitTypePieces(NarrowTy, NarrowRegs, 0); + unsigned Offset = isBigEndian ? TotalSize - NarrowTy.getSizeInBits() : 0; + unsigned HandledOffset = + splitTypePieces(NarrowTy, NarrowRegs, NumParts, Offset); // Handle the rest of the register if this isn't an even type breakdown. if (LeftoverTy.isValid()) - splitTypePieces(LeftoverTy, NarrowLeftoverRegs, HandledOffset); + splitTypePieces(LeftoverTy, NarrowLeftoverRegs, NumLeftover, HandledOffset); if (IsLoad) { insertParts(ValReg, ValTy, NarrowTy, NarrowRegs, @@ -4236,6 +4222,14 @@ LegalizerHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx, case G_INTTOPTR: case G_PTRTOINT: case G_ADDRSPACE_CAST: + case G_UADDO: + case G_USUBO: + case G_UADDE: + case G_USUBE: + case G_SADDO: + case G_SSUBO: + case G_SADDE: + case G_SSUBE: return fewerElementsVectorMultiEltType(GMI, NumElts); case G_ICMP: case G_FCMP: @@ -4882,10 +4876,26 @@ LegalizerHelper::moreElementsVector(MachineInstr &MI, unsigned TypeIdx, moreElementsVectorDst(MI, MoreTy, 0); Observer.changedInstr(MI); return Legalized; - case TargetOpcode::G_SELECT: - if (TypeIdx != 0) - return UnableToLegalize; - if (MRI.getType(MI.getOperand(1).getReg()).isVector()) + case TargetOpcode::G_SELECT: { + Register DstReg = MI.getOperand(0).getReg(); + Register CondReg = MI.getOperand(1).getReg(); + LLT DstTy = MRI.getType(DstReg); + LLT CondTy = MRI.getType(CondReg); + if (TypeIdx == 1) { + if (!CondTy.isScalar() || + DstTy.getElementCount() != MoreTy.getElementCount()) + return UnableToLegalize; + + // This is turning a scalar select of vectors into a vector + // select. Broadcast the select condition. + auto ShufSplat = MIRBuilder.buildShuffleSplat(MoreTy, CondReg); + Observer.changingInstr(MI); + MI.getOperand(1).setReg(ShufSplat.getReg(0)); + Observer.changedInstr(MI); + return Legalized; + } + + if (CondTy.isVector()) return UnableToLegalize; Observer.changingInstr(MI); @@ -4894,6 +4904,7 @@ LegalizerHelper::moreElementsVector(MachineInstr &MI, unsigned TypeIdx, moreElementsVectorDst(MI, MoreTy, 0); Observer.changedInstr(MI); return Legalized; + } case TargetOpcode::G_UNMERGE_VALUES: return UnableToLegalize; case TargetOpcode::G_PHI: @@ -7229,25 +7240,32 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerSelect(MachineInstr &MI) { Register Op2Reg = MI.getOperand(3).getReg(); LLT DstTy = MRI.getType(DstReg); LLT MaskTy = MRI.getType(MaskReg); - LLT Op1Ty = MRI.getType(Op1Reg); if (!DstTy.isVector()) return UnableToLegalize; - // Vector selects can have a scalar predicate. If so, splat into a vector and - // finish for later legalization attempts to try again. if (MaskTy.isScalar()) { + // Turn the scalar condition into a vector condition mask. + Register MaskElt = MaskReg; - if (MaskTy.getSizeInBits() < DstTy.getScalarSizeInBits()) - MaskElt = MIRBuilder.buildSExt(DstTy.getElementType(), MaskElt).getReg(0); - // Generate a vector splat idiom to be pattern matched later. + + // The condition was potentially zero extended before, but we want a sign + // extended boolean. + if (MaskTy.getSizeInBits() <= DstTy.getScalarSizeInBits() && + MaskTy != LLT::scalar(1)) { + MaskElt = MIRBuilder.buildSExtInReg(MaskTy, MaskElt, 1).getReg(0); + } + + // Continue the sign extension (or truncate) to match the data type. + MaskElt = MIRBuilder.buildSExtOrTrunc(DstTy.getElementType(), + MaskElt).getReg(0); + + // Generate a vector splat idiom. auto ShufSplat = MIRBuilder.buildShuffleSplat(DstTy, MaskElt); - Observer.changingInstr(MI); - MI.getOperand(1).setReg(ShufSplat.getReg(0)); - Observer.changedInstr(MI); - return Legalized; + MaskReg = ShufSplat.getReg(0); + MaskTy = DstTy; } - if (MaskTy.getSizeInBits() != Op1Ty.getSizeInBits()) { + if (MaskTy.getSizeInBits() != DstTy.getSizeInBits()) { return UnableToLegalize; } @@ -7414,7 +7432,7 @@ static Register getMemsetValue(Register Val, LLT Ty, MachineIRBuilder &MIB) { unsigned NumBits = Ty.getScalarSizeInBits(); auto ValVRegAndVal = getIConstantVRegValWithLookThrough(Val, MRI); if (!Ty.isVector() && ValVRegAndVal) { - APInt Scalar = ValVRegAndVal->Value.truncOrSelf(8); + APInt Scalar = ValVRegAndVal->Value.trunc(8); APInt SplatVal = APInt::getSplat(NumBits, Scalar); return MIB.buildConstant(Ty, SplatVal).getReg(0); } @@ -7569,7 +7587,7 @@ LegalizerHelper::lowerMemcpyInline(MachineInstr &MI) { // See if this is a constant length copy auto LenVRegAndVal = getIConstantVRegValWithLookThrough(Len, MRI); // FIXME: support dynamically sized G_MEMCPY_INLINE - assert(LenVRegAndVal.hasValue() && + assert(LenVRegAndVal && "inline memcpy with dynamic size is not yet supported"); uint64_t KnownLen = LenVRegAndVal->Value.getZExtValue(); if (KnownLen == 0) { @@ -7609,7 +7627,7 @@ LegalizerHelper::lowerMemcpy(MachineInstr &MI, Register Dst, Register Src, bool DstAlignCanChange = false; MachineFrameInfo &MFI = MF.getFrameInfo(); - Align Alignment = commonAlignment(DstAlign, SrcAlign); + Align Alignment = std::min(DstAlign, SrcAlign); MachineInstr *FIDef = getOpcodeDef(TargetOpcode::G_FRAME_INDEX, Dst, MRI); if (FIDef && !MFI.isFixedObjectIndex(FIDef->getOperand(1).getIndex())) @@ -7644,7 +7662,7 @@ LegalizerHelper::lowerMemcpy(MachineInstr &MI, Register Dst, Register Src, const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); if (!TRI->hasStackRealignment(MF)) while (NewAlign > Alignment && DL.exceedsNaturalStackAlignment(NewAlign)) - NewAlign = NewAlign / 2; + NewAlign = NewAlign.previous(); if (NewAlign > Alignment) { Alignment = NewAlign; @@ -7717,7 +7735,7 @@ LegalizerHelper::lowerMemmove(MachineInstr &MI, Register Dst, Register Src, bool DstAlignCanChange = false; MachineFrameInfo &MFI = MF.getFrameInfo(); bool OptSize = shouldLowerMemFuncForSize(MF); - Align Alignment = commonAlignment(DstAlign, SrcAlign); + Align Alignment = std::min(DstAlign, SrcAlign); MachineInstr *FIDef = getOpcodeDef(TargetOpcode::G_FRAME_INDEX, Dst, MRI); if (FIDef && !MFI.isFixedObjectIndex(FIDef->getOperand(1).getIndex())) @@ -7752,7 +7770,7 @@ LegalizerHelper::lowerMemmove(MachineInstr &MI, Register Dst, Register Src, const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); if (!TRI->hasStackRealignment(MF)) while (NewAlign > Alignment && DL.exceedsNaturalStackAlignment(NewAlign)) - NewAlign = NewAlign / 2; + NewAlign = NewAlign.previous(); if (NewAlign > Alignment) { Alignment = NewAlign; |