aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/GlobalISel
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/GlobalISel')
-rw-r--r--llvm/lib/CodeGen/GlobalISel/CallLowering.cpp11
-rw-r--r--llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp91
-rw-r--r--llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp43
-rw-r--r--llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp185
-rw-r--r--llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp67
-rw-r--r--llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp15
-rw-r--r--llvm/lib/CodeGen/GlobalISel/LegalityPredicates.cpp20
-rw-r--r--llvm/lib/CodeGen/GlobalISel/Legalizer.cpp4
-rw-r--r--llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp55
-rw-r--r--llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp10
-rw-r--r--llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp9
-rw-r--r--llvm/lib/CodeGen/GlobalISel/Utils.cpp27
12 files changed, 414 insertions, 123 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
index b3c3125..e2ed45e 100644
--- a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
@@ -196,6 +196,10 @@ bool CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, const CallBase &CB,
assert(Info.CFIType->getType()->isIntegerTy(32) && "Invalid CFI type");
}
+ if (auto Bundle = CB.getOperandBundle(LLVMContext::OB_deactivation_symbol)) {
+ Info.DeactivationSymbol = cast<GlobalValue>(Bundle->Inputs[0]);
+ }
+
Info.CB = &CB;
Info.KnownCallees = CB.getMetadata(LLVMContext::MD_callees);
Info.CallConv = CallConv;
@@ -292,7 +296,8 @@ void CallLowering::splitToValueTypes(const ArgInfo &OrigArg,
LLVMContext &Ctx = OrigArg.Ty->getContext();
SmallVector<EVT, 4> SplitVTs;
- ComputeValueVTs(*TLI, DL, OrigArg.Ty, SplitVTs, Offsets, 0);
+ ComputeValueVTs(*TLI, DL, OrigArg.Ty, SplitVTs, /*MemVTs=*/nullptr, Offsets,
+ 0);
if (SplitVTs.size() == 0)
return;
@@ -996,7 +1001,7 @@ void CallLowering::insertSRetLoads(MachineIRBuilder &MIRBuilder, Type *RetTy,
SmallVector<EVT, 4> SplitVTs;
SmallVector<uint64_t, 4> Offsets;
- ComputeValueVTs(*TLI, DL, RetTy, SplitVTs, &Offsets, 0);
+ ComputeValueVTs(*TLI, DL, RetTy, SplitVTs, /*MemVTs=*/nullptr, &Offsets, 0);
assert(VRegs.size() == SplitVTs.size());
@@ -1028,7 +1033,7 @@ void CallLowering::insertSRetStores(MachineIRBuilder &MIRBuilder, Type *RetTy,
SmallVector<EVT, 4> SplitVTs;
SmallVector<uint64_t, 4> Offsets;
- ComputeValueVTs(*TLI, DL, RetTy, SplitVTs, &Offsets, 0);
+ ComputeValueVTs(*TLI, DL, RetTy, SplitVTs, /*MemVTs=*/nullptr, &Offsets, 0);
assert(VRegs.size() == SplitVTs.size());
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 9ace7d6..f0fbe01 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -589,8 +589,8 @@ bool CombinerHelper::matchCombineShuffleVector(
return true;
}
-void CombinerHelper::applyCombineShuffleVector(
- MachineInstr &MI, const ArrayRef<Register> Ops) const {
+void CombinerHelper::applyCombineShuffleVector(MachineInstr &MI,
+ ArrayRef<Register> Ops) const {
Register DstReg = MI.getOperand(0).getReg();
Builder.setInsertPt(*MI.getParent(), MI);
Register NewDstReg = MRI.cloneVirtualRegister(DstReg);
@@ -3463,6 +3463,91 @@ static bool isConstValidTrue(const TargetLowering &TLI, unsigned ScalarSizeBits,
isConstTrueVal(TLI, Cst, IsVector, IsFP);
}
+// This pattern aims to match the following shape to avoid extra mov
+// instructions
+// G_BUILD_VECTOR(
+// G_UNMERGE_VALUES(src, 0)
+// G_UNMERGE_VALUES(src, 1)
+// G_IMPLICIT_DEF
+// G_IMPLICIT_DEF
+// )
+// ->
+// G_CONCAT_VECTORS(
+// src,
+// undef
+// )
+bool CombinerHelper::matchCombineBuildUnmerge(MachineInstr &MI,
+ MachineRegisterInfo &MRI,
+ Register &UnmergeSrc) const {
+ auto &BV = cast<GBuildVector>(MI);
+
+ unsigned BuildUseCount = BV.getNumSources();
+ if (BuildUseCount % 2 != 0)
+ return false;
+
+ unsigned NumUnmerge = BuildUseCount / 2;
+
+ auto *Unmerge = getOpcodeDef<GUnmerge>(BV.getSourceReg(0), MRI);
+
+ // Check the first operand is an unmerge and has the correct number of
+ // operands
+ if (!Unmerge || Unmerge->getNumDefs() != NumUnmerge)
+ return false;
+
+ UnmergeSrc = Unmerge->getSourceReg();
+
+ LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
+ LLT UnmergeSrcTy = MRI.getType(UnmergeSrc);
+
+ if (!UnmergeSrcTy.isVector())
+ return false;
+
+ // Ensure we only generate legal instructions post-legalizer
+ if (!IsPreLegalize &&
+ !isLegal({TargetOpcode::G_CONCAT_VECTORS, {DstTy, UnmergeSrcTy}}))
+ return false;
+
+ // Check that all of the operands before the midpoint come from the same
+ // unmerge and are in the same order as they are used in the build_vector
+ for (unsigned I = 0; I < NumUnmerge; ++I) {
+ auto MaybeUnmergeReg = BV.getSourceReg(I);
+ auto *LoopUnmerge = getOpcodeDef<GUnmerge>(MaybeUnmergeReg, MRI);
+
+ if (!LoopUnmerge || LoopUnmerge != Unmerge)
+ return false;
+
+ if (LoopUnmerge->getOperand(I).getReg() != MaybeUnmergeReg)
+ return false;
+ }
+
+ // Check that all of the unmerged values are used
+ if (Unmerge->getNumDefs() != NumUnmerge)
+ return false;
+
+ // Check that all of the operands after the mid point are undefs.
+ for (unsigned I = NumUnmerge; I < BuildUseCount; ++I) {
+ auto *Undef = getDefIgnoringCopies(BV.getSourceReg(I), MRI);
+
+ if (Undef->getOpcode() != TargetOpcode::G_IMPLICIT_DEF)
+ return false;
+ }
+
+ return true;
+}
+
+void CombinerHelper::applyCombineBuildUnmerge(MachineInstr &MI,
+ MachineRegisterInfo &MRI,
+ MachineIRBuilder &B,
+ Register &UnmergeSrc) const {
+ assert(UnmergeSrc && "Expected there to be one matching G_UNMERGE_VALUES");
+ B.setInstrAndDebugLoc(MI);
+
+ Register UndefVec = B.buildUndef(MRI.getType(UnmergeSrc)).getReg(0);
+ B.buildConcatVectors(MI.getOperand(0), {UnmergeSrc, UndefVec});
+
+ MI.eraseFromParent();
+}
+
// This combine tries to reduce the number of scalarised G_TRUNC instructions by
// using vector truncates instead
//
@@ -8426,4 +8511,4 @@ bool CombinerHelper::matchSuboCarryOut(const MachineInstr &MI,
}
return false;
-}
+} \ No newline at end of file
diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index d6f23b6..ecba323 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -247,6 +247,7 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known,
for (unsigned Idx = 1; Idx < MI.getNumOperands(); Idx += 2) {
const MachineOperand &Src = MI.getOperand(Idx);
Register SrcReg = Src.getReg();
+ LLT SrcTy = MRI.getType(SrcReg);
// Look through trivial copies and phis but don't look through trivial
// copies or phis of the form `%1:(s32) = OP %0:gpr32`, known-bits
// analysis is currently unable to determine the bit width of a
@@ -255,9 +256,15 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known,
// We can't use NoSubRegister by name as it's defined by each target but
// it's always defined to be 0 by tablegen.
if (SrcReg.isVirtual() && Src.getSubReg() == 0 /*NoSubRegister*/ &&
- MRI.getType(SrcReg).isValid()) {
+ SrcTy.isValid()) {
+ // In case we're forwarding from a vector register to a non-vector
+ // register we need to update the demanded elements to reflect this
+ // before recursing.
+ APInt NowDemandedElts = SrcTy.isFixedVector() && !DstTy.isFixedVector()
+ ? APInt::getAllOnes(SrcTy.getNumElements())
+ : DemandedElts; // Known to be APInt(1, 1)
// For COPYs we don't do anything, don't increase the depth.
- computeKnownBitsImpl(SrcReg, Known2, DemandedElts,
+ computeKnownBitsImpl(SrcReg, Known2, NowDemandedElts,
Depth + (Opcode != TargetOpcode::COPY));
Known2 = Known2.anyextOrTrunc(BitWidth);
Known = Known.intersectWith(Known2);
@@ -643,6 +650,38 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known,
Known.Zero.setBitsFrom(LowBits);
break;
}
+ case TargetOpcode::G_EXTRACT_VECTOR_ELT: {
+ GExtractVectorElement &Extract = cast<GExtractVectorElement>(MI);
+ Register InVec = Extract.getVectorReg();
+ Register EltNo = Extract.getIndexReg();
+
+ auto ConstEltNo = getIConstantVRegVal(EltNo, MRI);
+
+ LLT VecVT = MRI.getType(InVec);
+ // computeKnownBits not yet implemented for scalable vectors.
+ if (VecVT.isScalableVector())
+ break;
+
+ const unsigned EltBitWidth = VecVT.getScalarSizeInBits();
+ const unsigned NumSrcElts = VecVT.getNumElements();
+ // A return type different from the vector's element type may lead to
+ // issues with pattern selection. Bail out to avoid that.
+ if (BitWidth > EltBitWidth)
+ break;
+
+ Known.Zero.setAllBits();
+ Known.One.setAllBits();
+
+ // If we know the element index, just demand that vector element, else for
+ // an unknown element index, ignore DemandedElts and demand them all.
+ APInt DemandedSrcElts = APInt::getAllOnes(NumSrcElts);
+ if (ConstEltNo && ConstEltNo->ult(NumSrcElts))
+ DemandedSrcElts =
+ APInt::getOneBitSet(NumSrcElts, ConstEltNo->getZExtValue());
+
+ computeKnownBitsImpl(InVec, Known, DemandedSrcElts, Depth + 1);
+ break;
+ }
case TargetOpcode::G_SHUFFLE_VECTOR: {
APInt DemandedLHS, DemandedRHS;
// Collect the known bits that are shared by every vector element referenced
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 1fc90d0..d87a231 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -111,17 +111,18 @@ INITIALIZE_PASS_END(IRTranslator, DEBUG_TYPE, "IRTranslator LLVM IR -> MI",
false, false)
static void reportTranslationError(MachineFunction &MF,
- const TargetPassConfig &TPC,
OptimizationRemarkEmitter &ORE,
OptimizationRemarkMissed &R) {
MF.getProperties().setFailedISel();
+ bool IsGlobalISelAbortEnabled =
+ MF.getTarget().Options.GlobalISelAbort == GlobalISelAbortMode::Enable;
// Print the function name explicitly if we don't have a debug location (which
// makes the diagnostic less useful) or if we're going to emit a raw error.
- if (!R.getLocation().isValid() || TPC.isGlobalISelAbortEnabled())
+ if (!R.getLocation().isValid() || IsGlobalISelAbortEnabled)
R << (" (in function: " + MF.getName() + ")").str();
- if (TPC.isGlobalISelAbortEnabled())
+ if (IsGlobalISelAbortEnabled)
report_fatal_error(Twine(R.getMsg()));
else
ORE.emit(R);
@@ -242,7 +243,7 @@ ArrayRef<Register> IRTranslator::getOrCreateVRegs(const Value &Val) {
MF->getFunction().getSubprogram(),
&MF->getFunction().getEntryBlock());
R << "unable to translate constant: " << ore::NV("Type", Val.getType());
- reportTranslationError(*MF, *TPC, *ORE, R);
+ reportTranslationError(*MF, *ORE, R);
return *VRegs;
}
}
@@ -279,7 +280,7 @@ Align IRTranslator::getMemOpAlign(const Instruction &I) {
OptimizationRemarkMissed R("gisel-irtranslator", "", &I);
R << "unable to translate memop: " << ore::NV("Opcode", &I);
- reportTranslationError(*MF, *TPC, *ORE, R);
+ reportTranslationError(*MF, *ORE, R);
return Align(1);
}
@@ -294,6 +295,10 @@ void IRTranslator::addMachineCFGPred(CFGEdge Edge, MachineBasicBlock *NewPred) {
MachinePreds[Edge].push_back(NewPred);
}
+static bool targetSupportsBF16Type(const MachineFunction *MF) {
+ return MF->getTarget().getTargetTriple().isSPIRV();
+}
+
static bool containsBF16Type(const User &U) {
// BF16 cannot currently be represented by LLT, to avoid miscompiles we
// prevent any instructions using them. FIXME: This can be removed once LLT
@@ -306,7 +311,7 @@ static bool containsBF16Type(const User &U) {
bool IRTranslator::translateBinaryOp(unsigned Opcode, const User &U,
MachineIRBuilder &MIRBuilder) {
- if (containsBF16Type(U))
+ if (containsBF16Type(U) && !targetSupportsBF16Type(MF))
return false;
// Get or create a virtual register for each value.
@@ -328,7 +333,7 @@ bool IRTranslator::translateBinaryOp(unsigned Opcode, const User &U,
bool IRTranslator::translateUnaryOp(unsigned Opcode, const User &U,
MachineIRBuilder &MIRBuilder) {
- if (containsBF16Type(U))
+ if (containsBF16Type(U) && !targetSupportsBF16Type(MF))
return false;
Register Op0 = getOrCreateVReg(*U.getOperand(0));
@@ -348,7 +353,7 @@ bool IRTranslator::translateFNeg(const User &U, MachineIRBuilder &MIRBuilder) {
bool IRTranslator::translateCompare(const User &U,
MachineIRBuilder &MIRBuilder) {
- if (containsBF16Type(U))
+ if (containsBF16Type(U) && !targetSupportsBF16Type(MF))
return false;
auto *CI = cast<CmpInst>(&U);
@@ -1408,14 +1413,14 @@ bool IRTranslator::translateLoad(const User &U, MachineIRBuilder &MIRBuilder) {
Regs.size() == 1 ? LI.getMetadata(LLVMContext::MD_range) : nullptr;
for (unsigned i = 0; i < Regs.size(); ++i) {
Register Addr;
- MIRBuilder.materializeObjectPtrOffset(Addr, Base, OffsetTy, Offsets[i] / 8);
+ MIRBuilder.materializeObjectPtrOffset(Addr, Base, OffsetTy, Offsets[i]);
- MachinePointerInfo Ptr(LI.getPointerOperand(), Offsets[i] / 8);
+ MachinePointerInfo Ptr(LI.getPointerOperand(), Offsets[i]);
Align BaseAlign = getMemOpAlign(LI);
- auto MMO = MF->getMachineMemOperand(
- Ptr, Flags, MRI->getType(Regs[i]),
- commonAlignment(BaseAlign, Offsets[i] / 8), AAInfo, Ranges,
- LI.getSyncScopeID(), LI.getOrdering());
+ auto MMO =
+ MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Regs[i]),
+ commonAlignment(BaseAlign, Offsets[i]), AAInfo,
+ Ranges, LI.getSyncScopeID(), LI.getOrdering());
MIRBuilder.buildLoad(Regs[i], Addr, *MMO);
}
@@ -1447,14 +1452,14 @@ bool IRTranslator::translateStore(const User &U, MachineIRBuilder &MIRBuilder) {
for (unsigned i = 0; i < Vals.size(); ++i) {
Register Addr;
- MIRBuilder.materializeObjectPtrOffset(Addr, Base, OffsetTy, Offsets[i] / 8);
+ MIRBuilder.materializeObjectPtrOffset(Addr, Base, OffsetTy, Offsets[i]);
- MachinePointerInfo Ptr(SI.getPointerOperand(), Offsets[i] / 8);
+ MachinePointerInfo Ptr(SI.getPointerOperand(), Offsets[i]);
Align BaseAlign = getMemOpAlign(SI);
- auto MMO = MF->getMachineMemOperand(
- Ptr, Flags, MRI->getType(Vals[i]),
- commonAlignment(BaseAlign, Offsets[i] / 8), SI.getAAMetadata(), nullptr,
- SI.getSyncScopeID(), SI.getOrdering());
+ auto MMO = MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Vals[i]),
+ commonAlignment(BaseAlign, Offsets[i]),
+ SI.getAAMetadata(), nullptr,
+ SI.getSyncScopeID(), SI.getOrdering());
MIRBuilder.buildStore(Vals[i], Addr, *MMO);
}
return true;
@@ -1479,8 +1484,8 @@ static uint64_t getOffsetFromIndices(const User &U, const DataLayout &DL) {
llvm::append_range(Indices, drop_begin(U.operands()));
}
- return 8 * static_cast<uint64_t>(
- DL.getIndexedOffsetInType(Src->getType(), Indices));
+ return static_cast<uint64_t>(
+ DL.getIndexedOffsetInType(Src->getType(), Indices));
}
bool IRTranslator::translateExtractValue(const User &U,
@@ -1569,7 +1574,7 @@ bool IRTranslator::translateBitCast(const User &U,
bool IRTranslator::translateCast(unsigned Opcode, const User &U,
MachineIRBuilder &MIRBuilder) {
- if (containsBF16Type(U))
+ if (containsBF16Type(U) && !targetSupportsBF16Type(MF))
return false;
uint32_t Flags = 0;
@@ -2682,13 +2687,20 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
case Intrinsic::experimental_convergence_entry:
case Intrinsic::experimental_convergence_loop:
return translateConvergenceControlIntrinsic(CI, ID, MIRBuilder);
+ case Intrinsic::reloc_none: {
+ Metadata *MD = cast<MetadataAsValue>(CI.getArgOperand(0))->getMetadata();
+ StringRef SymbolName = cast<MDString>(MD)->getString();
+ MIRBuilder.buildInstr(TargetOpcode::RELOC_NONE)
+ .addExternalSymbol(SymbolName.data());
+ return true;
+ }
}
return false;
}
bool IRTranslator::translateInlineAsm(const CallBase &CB,
MachineIRBuilder &MIRBuilder) {
- if (containsBF16Type(CB))
+ if (containsBF16Type(CB) && !targetSupportsBF16Type(MF))
return false;
const InlineAsmLowering *ALI = MF->getSubtarget().getInlineAsmLowering();
@@ -2779,7 +2791,7 @@ bool IRTranslator::translateCallBase(const CallBase &CB,
}
bool IRTranslator::translateCall(const User &U, MachineIRBuilder &MIRBuilder) {
- if (!MF->getTarget().getTargetTriple().isSPIRV() && containsBF16Type(U))
+ if (containsBF16Type(U) && !targetSupportsBF16Type(MF))
return false;
const CallInst &CI = cast<CallInst>(U);
@@ -2817,20 +2829,34 @@ bool IRTranslator::translateCall(const User &U, MachineIRBuilder &MIRBuilder) {
if (translateKnownIntrinsic(CI, ID, MIRBuilder))
return true;
+ TargetLowering::IntrinsicInfo Info;
+ bool IsTgtMemIntrinsic = TLI->getTgtMemIntrinsic(Info, CI, *MF, ID);
+
+ return translateIntrinsic(CI, ID, MIRBuilder,
+ IsTgtMemIntrinsic ? &Info : nullptr);
+}
+
+/// Translate a call or callbr to an intrinsic.
+/// Depending on whether TLI->getTgtMemIntrinsic() is true, TgtMemIntrinsicInfo
+/// is a pointer to the correspondingly populated IntrinsicInfo object.
+/// Otherwise, this pointer is null.
+bool IRTranslator::translateIntrinsic(
+ const CallBase &CB, Intrinsic::ID ID, MachineIRBuilder &MIRBuilder,
+ const TargetLowering::IntrinsicInfo *TgtMemIntrinsicInfo) {
ArrayRef<Register> ResultRegs;
- if (!CI.getType()->isVoidTy())
- ResultRegs = getOrCreateVRegs(CI);
+ if (!CB.getType()->isVoidTy())
+ ResultRegs = getOrCreateVRegs(CB);
// Ignore the callsite attributes. Backend code is most likely not expecting
// an intrinsic to sometimes have side effects and sometimes not.
MachineInstrBuilder MIB = MIRBuilder.buildIntrinsic(ID, ResultRegs);
- if (isa<FPMathOperator>(CI))
- MIB->copyIRFlags(CI);
+ if (isa<FPMathOperator>(CB))
+ MIB->copyIRFlags(CB);
- for (const auto &Arg : enumerate(CI.args())) {
+ for (const auto &Arg : enumerate(CB.args())) {
// If this is required to be an immediate, don't materialize it in a
// register.
- if (CI.paramHasAttr(Arg.index(), Attribute::ImmArg)) {
+ if (CB.paramHasAttr(Arg.index(), Attribute::ImmArg)) {
if (ConstantInt *CI = dyn_cast<ConstantInt>(Arg.value())) {
// imm arguments are more convenient than cimm (and realistically
// probably sufficient), so use them.
@@ -2859,35 +2885,42 @@ bool IRTranslator::translateCall(const User &U, MachineIRBuilder &MIRBuilder) {
}
// Add a MachineMemOperand if it is a target mem intrinsic.
- TargetLowering::IntrinsicInfo Info;
- // TODO: Add a GlobalISel version of getTgtMemIntrinsic.
- if (TLI->getTgtMemIntrinsic(Info, CI, *MF, ID)) {
- Align Alignment = Info.align.value_or(
- DL->getABITypeAlign(Info.memVT.getTypeForEVT(F->getContext())));
- LLT MemTy = Info.memVT.isSimple()
- ? getLLTForMVT(Info.memVT.getSimpleVT())
- : LLT::scalar(Info.memVT.getStoreSizeInBits());
+ if (TgtMemIntrinsicInfo) {
+ const Function *F = CB.getCalledFunction();
+
+ Align Alignment = TgtMemIntrinsicInfo->align.value_or(DL->getABITypeAlign(
+ TgtMemIntrinsicInfo->memVT.getTypeForEVT(F->getContext())));
+ LLT MemTy =
+ TgtMemIntrinsicInfo->memVT.isSimple()
+ ? getLLTForMVT(TgtMemIntrinsicInfo->memVT.getSimpleVT())
+ : LLT::scalar(TgtMemIntrinsicInfo->memVT.getStoreSizeInBits());
// TODO: We currently just fallback to address space 0 if getTgtMemIntrinsic
// didn't yield anything useful.
MachinePointerInfo MPI;
- if (Info.ptrVal)
- MPI = MachinePointerInfo(Info.ptrVal, Info.offset);
- else if (Info.fallbackAddressSpace)
- MPI = MachinePointerInfo(*Info.fallbackAddressSpace);
+ if (TgtMemIntrinsicInfo->ptrVal) {
+ MPI = MachinePointerInfo(TgtMemIntrinsicInfo->ptrVal,
+ TgtMemIntrinsicInfo->offset);
+ } else if (TgtMemIntrinsicInfo->fallbackAddressSpace) {
+ MPI = MachinePointerInfo(*TgtMemIntrinsicInfo->fallbackAddressSpace);
+ }
MIB.addMemOperand(MF->getMachineMemOperand(
- MPI, Info.flags, MemTy, Alignment, CI.getAAMetadata(),
- /*Ranges=*/nullptr, Info.ssid, Info.order, Info.failureOrder));
+ MPI, TgtMemIntrinsicInfo->flags, MemTy, Alignment, CB.getAAMetadata(),
+ /*Ranges=*/nullptr, TgtMemIntrinsicInfo->ssid,
+ TgtMemIntrinsicInfo->order, TgtMemIntrinsicInfo->failureOrder));
}
- if (CI.isConvergent()) {
- if (auto Bundle = CI.getOperandBundle(LLVMContext::OB_convergencectrl)) {
+ if (CB.isConvergent()) {
+ if (auto Bundle = CB.getOperandBundle(LLVMContext::OB_convergencectrl)) {
auto *Token = Bundle->Inputs[0].get();
Register TokenReg = getOrCreateVReg(*Token);
MIB.addUse(TokenReg, RegState::Implicit);
}
}
+ if (auto Bundle = CB.getOperandBundle(LLVMContext::OB_deactivation_symbol))
+ MIB->setDeactivationSymbol(*MF, Bundle->Inputs[0].get());
+
return true;
}
@@ -3034,10 +3067,52 @@ bool IRTranslator::translateInvoke(const User &U,
return true;
}
+/// The intrinsics currently supported by callbr are implicit control flow
+/// intrinsics such as amdgcn.kill.
bool IRTranslator::translateCallBr(const User &U,
MachineIRBuilder &MIRBuilder) {
- // FIXME: Implement this.
- return false;
+ if (containsBF16Type(U))
+ return false; // see translateCall
+
+ const CallBrInst &I = cast<CallBrInst>(U);
+ MachineBasicBlock *CallBrMBB = &MIRBuilder.getMBB();
+
+ Intrinsic::ID IID = I.getIntrinsicID();
+ if (I.isInlineAsm()) {
+ // FIXME: inline asm is not yet supported for callbr in GlobalISel. As soon
+ // as we add support, we need to handle the indirect asm targets, see
+ // SelectionDAGBuilder::visitCallBr().
+ return false;
+ }
+ if (!translateIntrinsic(I, IID, MIRBuilder))
+ return false;
+
+ // Retrieve successors.
+ SmallPtrSet<BasicBlock *, 8> Dests = {I.getDefaultDest()};
+ MachineBasicBlock *Return = &getMBB(*I.getDefaultDest());
+
+ // Update successor info.
+ addSuccessorWithProb(CallBrMBB, Return, BranchProbability::getOne());
+
+ // Add indirect targets as successors. For intrinsic callbr, these represent
+ // implicit control flow (e.g., the "kill" path for amdgcn.kill). We mark them
+ // with setIsInlineAsmBrIndirectTarget so the machine verifier accepts them as
+ // valid successors, even though they're not from inline asm.
+ for (BasicBlock *Dest : I.getIndirectDests()) {
+ MachineBasicBlock &Target = getMBB(*Dest);
+ Target.setIsInlineAsmBrIndirectTarget();
+ Target.setLabelMustBeEmitted();
+ // Don't add duplicate machine successors.
+ if (Dests.insert(Dest).second)
+ addSuccessorWithProb(CallBrMBB, &Target, BranchProbability::getZero());
+ }
+
+ CallBrMBB->normalizeSuccProbs();
+
+ // Drop into default successor.
+ MIRBuilder.buildBr(*Return);
+
+ return true;
}
bool IRTranslator::translateLandingPad(const User &U,
@@ -3453,7 +3528,7 @@ bool IRTranslator::translateAtomicCmpXchg(const User &U,
bool IRTranslator::translateAtomicRMW(const User &U,
MachineIRBuilder &MIRBuilder) {
- if (containsBF16Type(U))
+ if (containsBF16Type(U) && !targetSupportsBF16Type(MF))
return false;
const AtomicRMWInst &I = cast<AtomicRMWInst>(U);
@@ -4115,7 +4190,7 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
OptimizationRemarkMissed R("gisel-irtranslator", "GISelFailure",
F.getSubprogram(), &F.getEntryBlock());
R << "unable to translate in big endian mode";
- reportTranslationError(*MF, *TPC, *ORE, R);
+ reportTranslationError(*MF, *ORE, R);
return false;
}
@@ -4159,7 +4234,7 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
F.getSubprogram(), &F.getEntryBlock());
R << "unable to lower function: "
<< ore::NV("Prototype", F.getFunctionType());
- reportTranslationError(*MF, *TPC, *ORE, R);
+ reportTranslationError(*MF, *ORE, R);
return false;
}
@@ -4182,7 +4257,7 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
F.getSubprogram(), &F.getEntryBlock());
R << "unable to lower arguments: "
<< ore::NV("Prototype", F.getFunctionType());
- reportTranslationError(*MF, *TPC, *ORE, R);
+ reportTranslationError(*MF, *ORE, R);
return false;
}
@@ -4233,7 +4308,7 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
R << ": '" << InstStrStorage << "'";
}
- reportTranslationError(*MF, *TPC, *ORE, R);
+ reportTranslationError(*MF, *ORE, R);
return false;
}
@@ -4241,7 +4316,7 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
OptimizationRemarkMissed R("gisel-irtranslator", "GISelFailure",
BB->getTerminator()->getDebugLoc(), BB);
R << "unable to translate basic block";
- reportTranslationError(*MF, *TPC, *ORE, R);
+ reportTranslationError(*MF, *ORE, R);
return false;
}
}
diff --git a/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp b/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
index b4e64d7..f695a2d 100644
--- a/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/InlineAsmLowering.cpp
@@ -13,6 +13,7 @@
#include "llvm/CodeGen/GlobalISel/InlineAsmLowering.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetLowering.h"
@@ -454,26 +455,52 @@ bool InlineAsmLowering::lowerInlineAsm(
}
if (OpInfo.ConstraintType == TargetLowering::C_Memory) {
-
- if (!OpInfo.isIndirect) {
- LLVM_DEBUG(dbgs()
- << "Cannot indirectify memory input operands yet\n");
- return false;
- }
-
- assert(OpInfo.isIndirect && "Operand must be indirect to be a mem!");
-
const InlineAsm::ConstraintCode ConstraintID =
TLI->getInlineAsmMemConstraint(OpInfo.ConstraintCode);
InlineAsm::Flag OpFlags(InlineAsm::Kind::Mem, 1);
OpFlags.setMemConstraint(ConstraintID);
Inst.addImm(OpFlags);
+
+ if (OpInfo.isIndirect) {
+ // already indirect
+ ArrayRef<Register> SourceRegs =
+ GetOrCreateVRegs(*OpInfo.CallOperandVal);
+ if (SourceRegs.size() != 1) {
+ LLVM_DEBUG(dbgs() << "Expected the memory input to fit into a "
+ "single virtual register "
+ "for constraint '"
+ << OpInfo.ConstraintCode << "'\n");
+ return false;
+ }
+ Inst.addReg(SourceRegs[0]);
+ break;
+ }
+
+ // Needs to be made indirect. Store the value on the stack and use
+ // a pointer to it.
+ Value *OpVal = OpInfo.CallOperandVal;
+ TypeSize Bytes = DL.getTypeStoreSize(OpVal->getType());
+ Align Alignment = DL.getPrefTypeAlign(OpVal->getType());
+ int FrameIdx =
+ MF.getFrameInfo().CreateStackObject(Bytes, Alignment, false);
+
+ unsigned AddrSpace = DL.getAllocaAddrSpace();
+ LLT FramePtrTy =
+ LLT::pointer(AddrSpace, DL.getPointerSizeInBits(AddrSpace));
+ auto Ptr = MIRBuilder.buildFrameIndex(FramePtrTy, FrameIdx).getReg(0);
ArrayRef<Register> SourceRegs =
GetOrCreateVRegs(*OpInfo.CallOperandVal);
- assert(
- SourceRegs.size() == 1 &&
- "Expected the memory input to fit into a single virtual register");
- Inst.addReg(SourceRegs[0]);
+ if (SourceRegs.size() != 1) {
+ LLVM_DEBUG(dbgs() << "Expected the memory input to fit into a single "
+ "virtual register "
+ "for constraint '"
+ << OpInfo.ConstraintCode << "'\n");
+ return false;
+ }
+ MIRBuilder.buildStore(SourceRegs[0], Ptr,
+ MachinePointerInfo::getFixedStack(MF, FrameIdx),
+ Alignment);
+ Inst.addReg(Ptr);
break;
}
@@ -538,13 +565,6 @@ bool InlineAsmLowering::lowerInlineAsm(
}
}
- // Add rounding control registers as implicit def for inline asm.
- if (MF.getFunction().hasFnAttribute(Attribute::StrictFP)) {
- ArrayRef<MCPhysReg> RCRegs = TLI->getRoundingControlRegisters();
- for (MCPhysReg Reg : RCRegs)
- Inst.addReg(Reg, RegState::ImplicitDefine);
- }
-
if (auto Bundle = Call.getOperandBundle(LLVMContext::OB_convergencectrl)) {
auto *Token = Bundle->Inputs[0].get();
ArrayRef<Register> SourceRegs = GetOrCreateVRegs(*Token);
@@ -556,6 +576,13 @@ bool InlineAsmLowering::lowerInlineAsm(
if (const MDNode *SrcLoc = Call.getMetadata("srcloc"))
Inst.addMetadata(SrcLoc);
+ // Add rounding control registers as implicit def for inline asm.
+ if (MF.getFunction().hasFnAttribute(Attribute::StrictFP)) {
+ ArrayRef<MCPhysReg> RCRegs = TLI->getRoundingControlRegisters();
+ for (MCPhysReg Reg : RCRegs)
+ Inst.addReg(Reg, RegState::ImplicitDefine);
+ }
+
// All inputs are handled, insert the instruction now
MIRBuilder.insertInstr(Inst);
diff --git a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
index 2dd22c8a..1d281ab 100644
--- a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
@@ -137,7 +137,6 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
return false;
ISel = MF.getSubtarget().getInstructionSelector();
- ISel->TPC = &getAnalysis<TargetPassConfig>();
// FIXME: Properly override OptLevel in TargetMachine. See OptLevelChanger
CodeGenOptLevel OldOptLevel = OptLevel;
@@ -159,7 +158,6 @@ bool InstructionSelect::selectMachineFunction(MachineFunction &MF) {
LLVM_DEBUG(dbgs() << "Selecting function: " << MF.getName() << '\n');
assert(ISel && "Cannot work without InstructionSelector");
- const TargetPassConfig &TPC = *ISel->TPC;
CodeGenCoverage CoverageInfo;
ISel->setupMF(MF, VT, &CoverageInfo, PSI, BFI);
@@ -177,8 +175,8 @@ bool InstructionSelect::selectMachineFunction(MachineFunction &MF) {
// property check already is.
if (!DisableGISelLegalityCheck)
if (const MachineInstr *MI = machineFunctionIsIllegal(MF)) {
- reportGISelFailure(MF, TPC, MORE, "gisel-select",
- "instruction is not legal", *MI);
+ reportGISelFailure(MF, MORE, "gisel-select", "instruction is not legal",
+ *MI);
return false;
}
// FIXME: We could introduce new blocks and will need to fix the outer loop.
@@ -215,8 +213,7 @@ bool InstructionSelect::selectMachineFunction(MachineFunction &MF) {
if (!selectInstr(MI)) {
LLVM_DEBUG(dbgs() << "Selection failed!\n";
MIIMaintainer.reportFullyCreatedInstrs());
- reportGISelFailure(MF, TPC, MORE, "gisel-select", "cannot select",
- MI);
+ reportGISelFailure(MF, MORE, "gisel-select", "cannot select", MI);
return false;
}
LLVM_DEBUG(MIIMaintainer.reportFullyCreatedInstrs());
@@ -279,7 +276,7 @@ bool InstructionSelect::selectMachineFunction(MachineFunction &MF) {
const TargetRegisterClass *RC = MRI.getRegClassOrNull(VReg);
if (!RC) {
- reportGISelFailure(MF, TPC, MORE, "gisel-select",
+ reportGISelFailure(MF, MORE, "gisel-select",
"VReg has no regclass after selection", *MI);
return false;
}
@@ -288,7 +285,7 @@ bool InstructionSelect::selectMachineFunction(MachineFunction &MF) {
if (Ty.isValid() &&
TypeSize::isKnownGT(Ty.getSizeInBits(), TRI.getRegSizeInBits(*RC))) {
reportGISelFailure(
- MF, TPC, MORE, "gisel-select",
+ MF, MORE, "gisel-select",
"VReg's low-level type and register class have different sizes", *MI);
return false;
}
@@ -299,7 +296,7 @@ bool InstructionSelect::selectMachineFunction(MachineFunction &MF) {
MF.getFunction().getSubprogram(),
/*MBB=*/nullptr);
R << "inserting blocks is not supported yet";
- reportGISelFailure(MF, TPC, MORE, R);
+ reportGISelFailure(MF, MORE, R);
return false;
}
#endif
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalityPredicates.cpp b/llvm/lib/CodeGen/GlobalISel/LegalityPredicates.cpp
index 30c2d08..5e7cd5f 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalityPredicates.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalityPredicates.cpp
@@ -155,6 +155,26 @@ LegalityPredicate LegalityPredicates::scalarOrEltNarrowerThan(unsigned TypeIdx,
};
}
+LegalityPredicate
+LegalityPredicates::vectorElementCountIsGreaterThan(unsigned TypeIdx,
+ unsigned Size) {
+
+ return [=](const LegalityQuery &Query) {
+ const LLT QueryTy = Query.Types[TypeIdx];
+ return QueryTy.isFixedVector() && QueryTy.getNumElements() > Size;
+ };
+}
+
+LegalityPredicate
+LegalityPredicates::vectorElementCountIsLessThanOrEqualTo(unsigned TypeIdx,
+ unsigned Size) {
+
+ return [=](const LegalityQuery &Query) {
+ const LLT QueryTy = Query.Types[TypeIdx];
+ return QueryTy.isFixedVector() && QueryTy.getNumElements() <= Size;
+ };
+}
+
LegalityPredicate LegalityPredicates::scalarOrEltWiderThan(unsigned TypeIdx,
unsigned Size) {
return [=](const LegalityQuery &Query) {
diff --git a/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp b/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp
index aef16b5..0f0656a 100644
--- a/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp
@@ -348,7 +348,7 @@ bool Legalizer::runOnMachineFunction(MachineFunction &MF) {
*MIRBuilder, VT);
if (Result.FailedOn) {
- reportGISelFailure(MF, TPC, MORE, "gisel-legalize",
+ reportGISelFailure(MF, MORE, "gisel-legalize",
"unable to legalize instruction", *Result.FailedOn);
return false;
}
@@ -360,7 +360,7 @@ bool Legalizer::runOnMachineFunction(MachineFunction &MF) {
R << "lost "
<< ore::NV("NumLostDebugLocs", LocObserver.getNumLostDebugLocs())
<< " debug locations during pass";
- reportGISelWarning(MF, TPC, MORE, R);
+ reportGISelWarning(MF, MORE, R);
// Example remark:
// --- !Missed
// Pass: gisel-legalize
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 52c43a4..251ea4b 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -776,7 +776,7 @@ llvm::createMemLibcall(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
break;
case TargetOpcode::G_MEMCPY:
RTLibcall = RTLIB::MEMCPY;
- Name = TLI.getMemcpyName();
+ Name = TLI.getLibcallImplName(TLI.getMemcpyImpl()).data();
Args[0].Flags[0].setReturned();
break;
case TargetOpcode::G_MEMMOVE:
@@ -1930,7 +1930,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
Register CmpOut;
CmpInst::Predicate PartPred;
- if (I == E - 1 && LHSLeftoverRegs.empty()) {
+ if (I == E - 1) {
PartPred = Pred;
CmpOut = Dst;
} else {
@@ -3065,6 +3065,14 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
Observer.changedInstr(MI);
return Legalized;
+ case TargetOpcode::G_FPEXT:
+ if (TypeIdx != 1)
+ return UnableToLegalize;
+
+ Observer.changingInstr(MI);
+ widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_FPEXT);
+ Observer.changedInstr(MI);
+ return Legalized;
case TargetOpcode::G_FPTOSI:
case TargetOpcode::G_FPTOUI:
case TargetOpcode::G_INTRINSIC_LRINT:
@@ -3431,6 +3439,18 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
Observer.changedInstr(MI);
return Legalized;
}
+ case TargetOpcode::G_LROUND:
+ case TargetOpcode::G_LLROUND:
+ Observer.changingInstr(MI);
+
+ if (TypeIdx == 0)
+ widenScalarDst(MI, WideTy);
+ else
+ widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_FPEXT);
+
+ Observer.changedInstr(MI);
+ return Legalized;
+
case TargetOpcode::G_INTTOPTR:
if (TypeIdx != 1)
return UnableToLegalize;
@@ -6664,13 +6684,24 @@ LegalizerHelper::moreElementsVector(MachineInstr &MI, unsigned TypeIdx,
case TargetOpcode::G_FMAXIMUMNUM:
case TargetOpcode::G_STRICT_FADD:
case TargetOpcode::G_STRICT_FSUB:
- case TargetOpcode::G_STRICT_FMUL:
+ case TargetOpcode::G_STRICT_FMUL: {
+ Observer.changingInstr(MI);
+ moreElementsVectorSrc(MI, MoreTy, 1);
+ moreElementsVectorSrc(MI, MoreTy, 2);
+ moreElementsVectorDst(MI, MoreTy, 0);
+ Observer.changedInstr(MI);
+ return Legalized;
+ }
case TargetOpcode::G_SHL:
case TargetOpcode::G_ASHR:
case TargetOpcode::G_LSHR: {
Observer.changingInstr(MI);
moreElementsVectorSrc(MI, MoreTy, 1);
- moreElementsVectorSrc(MI, MoreTy, 2);
+ // The shift operand may have a different scalar type from the source and
+ // destination operands.
+ LLT ShiftMoreTy = MoreTy.changeElementType(
+ MRI.getType(MI.getOperand(2).getReg()).getElementType());
+ moreElementsVectorSrc(MI, ShiftMoreTy, 2);
moreElementsVectorDst(MI, MoreTy, 0);
Observer.changedInstr(MI);
return Legalized;
@@ -6786,12 +6817,10 @@ LegalizerHelper::moreElementsVector(MachineInstr &MI, unsigned TypeIdx,
LLT DstExtTy;
if (TypeIdx == 0) {
DstExtTy = MoreTy;
- SrcExtTy = LLT::fixed_vector(
- MoreTy.getNumElements(),
+ SrcExtTy = MoreTy.changeElementType(
MRI.getType(MI.getOperand(1).getReg()).getElementType());
} else {
- DstExtTy = LLT::fixed_vector(
- MoreTy.getNumElements(),
+ DstExtTy = MoreTy.changeElementType(
MRI.getType(MI.getOperand(0).getReg()).getElementType());
SrcExtTy = MoreTy;
}
@@ -7589,7 +7618,7 @@ LegalizerHelper::lowerBitCount(MachineInstr &MI) {
}
case TargetOpcode::G_CTLZ: {
auto [DstReg, DstTy, SrcReg, SrcTy] = MI.getFirst2RegLLTs();
- unsigned Len = SrcTy.getSizeInBits();
+ unsigned Len = SrcTy.getScalarSizeInBits();
if (isSupported({TargetOpcode::G_CTLZ_ZERO_UNDEF, {DstTy, SrcTy}})) {
// If CTLZ_ZERO_UNDEF is supported, emit that and a select for zero.
@@ -7637,7 +7666,7 @@ LegalizerHelper::lowerBitCount(MachineInstr &MI) {
case TargetOpcode::G_CTTZ: {
auto [DstReg, DstTy, SrcReg, SrcTy] = MI.getFirst2RegLLTs();
- unsigned Len = SrcTy.getSizeInBits();
+ unsigned Len = SrcTy.getScalarSizeInBits();
if (isSupported({TargetOpcode::G_CTTZ_ZERO_UNDEF, {DstTy, SrcTy}})) {
// If CTTZ_ZERO_UNDEF is legal or custom, emit that and a select with
// zero.
@@ -7675,9 +7704,13 @@ LegalizerHelper::lowerBitCount(MachineInstr &MI) {
case TargetOpcode::G_CTPOP: {
Register SrcReg = MI.getOperand(1).getReg();
LLT Ty = MRI.getType(SrcReg);
- unsigned Size = Ty.getSizeInBits();
+ unsigned Size = Ty.getScalarSizeInBits();
MachineIRBuilder &B = MIRBuilder;
+ // Bail out on irregular type lengths.
+ if (Size > 128 || Size % 8 != 0)
+ return UnableToLegalize;
+
// Count set bits in blocks of 2 bits. Default approach would be
// B2Count = { val & 0x55555555 } + { (val >> 1) & 0x55555555 }
// We use following formula instead:
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index 4b4df98..3906b31 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -38,8 +38,10 @@ void MachineIRBuilder::setMF(MachineFunction &MF) {
//------------------------------------------------------------------------------
MachineInstrBuilder MachineIRBuilder::buildInstrNoInsert(unsigned Opcode) {
- return BuildMI(getMF(), {getDL(), getPCSections(), getMMRAMetadata()},
- getTII().get(Opcode));
+ return BuildMI(
+ getMF(),
+ {getDL(), getPCSections(), getMMRAMetadata(), getDeactivationSymbol()},
+ getTII().get(Opcode));
}
MachineInstrBuilder MachineIRBuilder::insertInstr(MachineInstrBuilder MIB) {
@@ -109,8 +111,10 @@ MachineInstrBuilder MachineIRBuilder::buildConstDbgValue(const Constant &C,
if (auto *CI = dyn_cast<ConstantInt>(NumericConstant)) {
if (CI->getBitWidth() > 64)
MIB.addCImm(CI);
- else
+ else if (CI->getBitWidth() == 1)
MIB.addImm(CI->getZExtValue());
+ else
+ MIB.addImm(CI->getSExtValue());
} else if (auto *CFP = dyn_cast<ConstantFP>(NumericConstant)) {
MIB.addFPImm(CFP);
} else if (isa<ConstantPointerNull>(NumericConstant)) {
diff --git a/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp b/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp
index bcb4f1c..5db631b 100644
--- a/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp
@@ -39,6 +39,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetMachine.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
@@ -83,7 +84,6 @@ void RegBankSelect::init(MachineFunction &MF) {
assert(RBI && "Cannot work without RegisterBankInfo");
MRI = &MF.getRegInfo();
TRI = MF.getSubtarget().getRegisterInfo();
- TPC = &getAnalysis<TargetPassConfig>();
if (OptMode != Mode::Fast) {
MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
MBPI = &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
@@ -308,7 +308,8 @@ const RegisterBankInfo::InstructionMapping &RegBankSelect::findBestMapping(
RepairPts.emplace_back(std::move(RepairPt));
}
}
- if (!BestMapping && !TPC->isGlobalISelAbortEnabled()) {
+ if (!BestMapping && MI.getMF()->getTarget().Options.GlobalISelAbort !=
+ GlobalISelAbortMode::Enable) {
// If none of the mapping worked that means they are all impossible.
// Thus, pick the first one and set an impossible repairing point.
// It will trigger the failed isel mode.
@@ -708,7 +709,7 @@ bool RegBankSelect::assignRegisterBanks(MachineFunction &MF) {
continue;
if (!assignInstr(MI)) {
- reportGISelFailure(MF, *TPC, *MORE, "gisel-regbankselect",
+ reportGISelFailure(MF, *MORE, "gisel-regbankselect",
"unable to map instruction", MI);
return false;
}
@@ -722,7 +723,7 @@ bool RegBankSelect::checkFunctionIsLegal(MachineFunction &MF) const {
#ifndef NDEBUG
if (!DisableGISelLegalityCheck) {
if (const MachineInstr *MI = machineFunctionIsIllegal(MF)) {
- reportGISelFailure(MF, *TPC, *MORE, "gisel-regbankselect",
+ reportGISelFailure(MF, *MORE, "gisel-regbankselect",
"instruction is not legal", *MI);
return false;
}
diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
index 5fab6ec..15e81f5 100644
--- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
@@ -114,7 +114,7 @@ Register llvm::constrainOperandRegClass(
// Assume physical registers are properly constrained.
assert(Reg.isVirtual() && "PhysReg not implemented");
- const TargetRegisterClass *OpRC = TII.getRegClass(II, OpIdx, &TRI);
+ const TargetRegisterClass *OpRC = TII.getRegClass(II, OpIdx);
// Some of the target independent instructions, like COPY, may not impose any
// register class constraints on some of their operands: If it's a use, we can
// skip constraining as the instruction defining the register would constrain
@@ -234,11 +234,11 @@ bool llvm::isTriviallyDead(const MachineInstr &MI,
static void reportGISelDiagnostic(DiagnosticSeverity Severity,
MachineFunction &MF,
- const TargetPassConfig &TPC,
MachineOptimizationRemarkEmitter &MORE,
MachineOptimizationRemarkMissed &R) {
- bool IsFatal = Severity == DS_Error &&
- TPC.isGlobalISelAbortEnabled();
+ bool IsGlobalISelAbortEnabled =
+ MF.getTarget().Options.GlobalISelAbort == GlobalISelAbortMode::Enable;
+ bool IsFatal = Severity == DS_Error && IsGlobalISelAbortEnabled;
// Print the function name explicitly if we don't have a debug location (which
// makes the diagnostic less useful) or if we're going to emit a raw error.
if (!R.getLocation().isValid() || IsFatal)
@@ -250,20 +250,20 @@ static void reportGISelDiagnostic(DiagnosticSeverity Severity,
MORE.emit(R);
}
-void llvm::reportGISelWarning(MachineFunction &MF, const TargetPassConfig &TPC,
+void llvm::reportGISelWarning(MachineFunction &MF,
MachineOptimizationRemarkEmitter &MORE,
MachineOptimizationRemarkMissed &R) {
- reportGISelDiagnostic(DS_Warning, MF, TPC, MORE, R);
+ reportGISelDiagnostic(DS_Warning, MF, MORE, R);
}
-void llvm::reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC,
+void llvm::reportGISelFailure(MachineFunction &MF,
MachineOptimizationRemarkEmitter &MORE,
MachineOptimizationRemarkMissed &R) {
MF.getProperties().setFailedISel();
- reportGISelDiagnostic(DS_Error, MF, TPC, MORE, R);
+ reportGISelDiagnostic(DS_Error, MF, MORE, R);
}
-void llvm::reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC,
+void llvm::reportGISelFailure(MachineFunction &MF,
MachineOptimizationRemarkEmitter &MORE,
const char *PassName, StringRef Msg,
const MachineInstr &MI) {
@@ -271,9 +271,10 @@ void llvm::reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC,
MI.getDebugLoc(), MI.getParent());
R << Msg;
// Printing MI is expensive; only do it if expensive remarks are enabled.
- if (TPC.isGlobalISelAbortEnabled() || MORE.allowExtraAnalysis(PassName))
+ if (MF.getTarget().Options.GlobalISelAbort == GlobalISelAbortMode::Enable ||
+ MORE.allowExtraAnalysis(PassName))
R << ": " << ore::MNV("Inst", MI);
- reportGISelFailure(MF, TPC, MORE, R);
+ reportGISelFailure(MF, MORE, R);
}
unsigned llvm::getInverseGMinMaxOpcode(unsigned MinMaxOpc) {
@@ -768,8 +769,12 @@ llvm::ConstantFoldFPBinOp(unsigned Opcode, const Register Op1,
C1.copySign(C2);
return C1;
case TargetOpcode::G_FMINNUM:
+ if (C1.isSignaling() || C2.isSignaling())
+ return std::nullopt;
return minnum(C1, C2);
case TargetOpcode::G_FMAXNUM:
+ if (C1.isSignaling() || C2.isSignaling())
+ return std::nullopt;
return maxnum(C1, C2);
case TargetOpcode::G_FMINIMUM:
return minimum(C1, C2);