summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/CodeGenPrepare.cpp6
-rw-r--r--llvm/lib/CodeGen/EarlyIfConversion.cpp43
-rw-r--r--llvm/lib/CodeGen/ExpandLargeFpConvert.cpp2
-rw-r--r--llvm/lib/CodeGen/ExpandMemCmp.cpp2
-rw-r--r--llvm/lib/CodeGen/ExpandVectorPredication.cpp14
-rw-r--r--llvm/lib/CodeGen/HardwareLoops.cpp12
-rw-r--r--llvm/lib/CodeGen/IntrinsicLowering.cpp2
-rw-r--r--llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp8
-rw-r--r--llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp25
-rw-r--r--llvm/lib/CodeGen/MachineBlockPlacement.cpp7
-rw-r--r--llvm/lib/CodeGen/MachineCopyPropagation.cpp7
-rw-r--r--llvm/lib/CodeGen/MachineVerifier.cpp583
-rw-r--r--llvm/lib/CodeGen/ReplaceWithVeclib.cpp25
-rw-r--r--llvm/lib/CodeGen/SafeStack.cpp3
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp17
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp3
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp2
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp32
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp5
-rw-r--r--llvm/lib/CodeGen/SjLjEHPrepare.cpp22
-rw-r--r--llvm/lib/CodeGen/StackProtector.cpp5
-rw-r--r--llvm/lib/CodeGen/WasmEHPrepare.cpp15
22 files changed, 459 insertions, 381 deletions
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 631cc26d6022..3e09fbad6ab1 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -7274,7 +7274,7 @@ bool CodeGenPrepare::optimizeShiftInst(BinaryOperator *Shift) {
// We can't do this effectively in SDAG because we may not be able to
// determine if the select operands are splats from within a basic block.
Type *Ty = Shift->getType();
- if (!Ty->isVectorTy() || !TLI->isVectorShiftByScalarCheap(Ty))
+ if (!Ty->isVectorTy() || !TTI->isVectorShiftByScalarCheap(Ty))
return false;
Value *Cond, *TVal, *FVal;
if (!match(Shift->getOperand(1),
@@ -7309,7 +7309,7 @@ bool CodeGenPrepare::optimizeFunnelShift(IntrinsicInst *Fsh) {
// We can't do this effectively in SDAG because we may not be able to
// determine if the select operands are splats from within a basic block.
Type *Ty = Fsh->getType();
- if (!Ty->isVectorTy() || !TLI->isVectorShiftByScalarCheap(Ty))
+ if (!Ty->isVectorTy() || !TTI->isVectorShiftByScalarCheap(Ty))
return false;
Value *Cond, *TVal, *FVal;
if (!match(Fsh->getOperand(2),
@@ -7566,7 +7566,7 @@ bool CodeGenPrepare::tryToSinkFreeOperands(Instruction *I) {
// If the operands of I can be folded into a target instruction together with
// I, duplicate and sink them.
SmallVector<Use *, 4> OpsToSink;
- if (!TLI->shouldSinkOperands(I, OpsToSink))
+ if (!TTI->isProfitableToSinkOperands(I, OpsToSink))
return false;
// OpsToSink can contain multiple uses in a use chain (e.g.
diff --git a/llvm/lib/CodeGen/EarlyIfConversion.cpp b/llvm/lib/CodeGen/EarlyIfConversion.cpp
index c827d5bdcf55..8d9813edd7e5 100644
--- a/llvm/lib/CodeGen/EarlyIfConversion.cpp
+++ b/llvm/lib/CodeGen/EarlyIfConversion.cpp
@@ -163,7 +163,8 @@ private:
void rewritePHIOperands();
public:
- SSAIfConv(MachineFunction &MF) {
+ /// init - Initialize per-function data structures.
+ void init(MachineFunction &MF) {
TII = MF.getSubtarget().getInstrInfo();
TRI = MF.getSubtarget().getRegisterInfo();
MRI = &MF.getRegInfo();
@@ -768,6 +769,7 @@ class EarlyIfConverter : public MachineFunctionPass {
MachineLoopInfo *Loops = nullptr;
MachineTraceMetrics *Traces = nullptr;
MachineTraceMetrics::Ensemble *MinInstr = nullptr;
+ SSAIfConv IfConv;
public:
static char ID;
@@ -777,9 +779,9 @@ public:
StringRef getPassName() const override { return "Early If-Conversion"; }
private:
- bool tryConvertIf(SSAIfConv &IfConv, MachineBasicBlock *);
- void invalidateTraces(SSAIfConv &IfConv);
- bool shouldConvertIf(SSAIfConv &IfConv);
+ bool tryConvertIf(MachineBasicBlock *);
+ void invalidateTraces();
+ bool shouldConvertIf();
};
} // end anonymous namespace
@@ -835,7 +837,7 @@ void updateLoops(MachineLoopInfo *Loops,
} // namespace
/// Invalidate MachineTraceMetrics before if-conversion.
-void EarlyIfConverter::invalidateTraces(SSAIfConv &IfConv) {
+void EarlyIfConverter::invalidateTraces() {
Traces->verifyAnalysis();
Traces->invalidate(IfConv.Head);
Traces->invalidate(IfConv.Tail);
@@ -865,7 +867,7 @@ template <typename Remark> Remark &operator<<(Remark &R, Cycles C) {
/// Apply cost model and heuristics to the if-conversion in IfConv.
/// Return true if the conversion is a good idea.
///
-bool EarlyIfConverter::shouldConvertIf(SSAIfConv &IfConv) {
+bool EarlyIfConverter::shouldConvertIf() {
// Stress testing mode disables all cost considerations.
if (Stress)
return true;
@@ -1058,11 +1060,11 @@ bool EarlyIfConverter::shouldConvertIf(SSAIfConv &IfConv) {
/// Attempt repeated if-conversion on MBB, return true if successful.
///
-bool EarlyIfConverter::tryConvertIf(SSAIfConv &IfConv, MachineBasicBlock *MBB) {
+bool EarlyIfConverter::tryConvertIf(MachineBasicBlock *MBB) {
bool Changed = false;
- while (IfConv.canConvertIf(MBB) && shouldConvertIf(IfConv)) {
+ while (IfConv.canConvertIf(MBB) && shouldConvertIf()) {
// If-convert MBB and update analyses.
- invalidateTraces(IfConv);
+ invalidateTraces();
SmallVector<MachineBasicBlock *, 4> RemoveBlocks;
IfConv.convertIf(RemoveBlocks);
Changed = true;
@@ -1095,14 +1097,14 @@ bool EarlyIfConverter::runOnMachineFunction(MachineFunction &MF) {
MinInstr = nullptr;
bool Changed = false;
- SSAIfConv IfConv(MF);
+ IfConv.init(MF);
// Visit blocks in dominator tree post-order. The post-order enables nested
// if-conversion in a single pass. The tryConvertIf() function may erase
// blocks, but only blocks dominated by the head block. This makes it safe to
// update the dominator tree while the post-order iterator is still active.
for (auto *DomNode : post_order(DomTree))
- if (tryConvertIf(IfConv, DomNode->getBlock()))
+ if (tryConvertIf(DomNode->getBlock()))
Changed = true;
return Changed;
@@ -1121,6 +1123,7 @@ class EarlyIfPredicator : public MachineFunctionPass {
MachineDominatorTree *DomTree = nullptr;
MachineBranchProbabilityInfo *MBPI = nullptr;
MachineLoopInfo *Loops = nullptr;
+ SSAIfConv IfConv;
public:
static char ID;
@@ -1130,8 +1133,8 @@ public:
StringRef getPassName() const override { return "Early If-predicator"; }
protected:
- bool tryConvertIf(SSAIfConv &IfConv, MachineBasicBlock *);
- bool shouldConvertIf(SSAIfConv &IfConv);
+ bool tryConvertIf(MachineBasicBlock *);
+ bool shouldConvertIf();
};
} // end anonymous namespace
@@ -1158,7 +1161,7 @@ void EarlyIfPredicator::getAnalysisUsage(AnalysisUsage &AU) const {
}
/// Apply the target heuristic to decide if the transformation is profitable.
-bool EarlyIfPredicator::shouldConvertIf(SSAIfConv &IfConv) {
+bool EarlyIfPredicator::shouldConvertIf() {
auto TrueProbability = MBPI->getEdgeProbability(IfConv.Head, IfConv.TBB);
if (IfConv.isTriangle()) {
MachineBasicBlock &IfBlock =
@@ -1198,14 +1201,12 @@ bool EarlyIfPredicator::shouldConvertIf(SSAIfConv &IfConv) {
/// Attempt repeated if-conversion on MBB, return true if successful.
///
-bool EarlyIfPredicator::tryConvertIf(SSAIfConv &IfConv,
- MachineBasicBlock *MBB) {
+bool EarlyIfPredicator::tryConvertIf(MachineBasicBlock *MBB) {
bool Changed = false;
- while (IfConv.canConvertIf(MBB, /*Predicate=*/true) &&
- shouldConvertIf(IfConv)) {
+ while (IfConv.canConvertIf(MBB, /*Predicate*/ true) && shouldConvertIf()) {
// If-convert MBB and update analyses.
SmallVector<MachineBasicBlock *, 4> RemoveBlocks;
- IfConv.convertIf(RemoveBlocks, /*Predicate=*/true);
+ IfConv.convertIf(RemoveBlocks, /*Predicate*/ true);
Changed = true;
updateDomTree(DomTree, IfConv, RemoveBlocks);
for (MachineBasicBlock *MBB : RemoveBlocks)
@@ -1231,14 +1232,14 @@ bool EarlyIfPredicator::runOnMachineFunction(MachineFunction &MF) {
MBPI = &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
bool Changed = false;
- SSAIfConv IfConv(MF);
+ IfConv.init(MF);
// Visit blocks in dominator tree post-order. The post-order enables nested
// if-conversion in a single pass. The tryConvertIf() function may erase
// blocks, but only blocks dominated by the head block. This makes it safe to
// update the dominator tree while the post-order iterator is still active.
for (auto *DomNode : post_order(DomTree))
- if (tryConvertIf(IfConv, DomNode->getBlock()))
+ if (tryConvertIf(DomNode->getBlock()))
Changed = true;
return Changed;
diff --git a/llvm/lib/CodeGen/ExpandLargeFpConvert.cpp b/llvm/lib/CodeGen/ExpandLargeFpConvert.cpp
index 11f123aa5bed..0a3d0cf8ec93 100644
--- a/llvm/lib/CodeGen/ExpandLargeFpConvert.cpp
+++ b/llvm/lib/CodeGen/ExpandLargeFpConvert.cpp
@@ -356,7 +356,7 @@ static void expandIToFP(Instruction *IToFP) {
Entry->getTerminator()->eraseFromParent();
Function *CTLZ =
- Intrinsic::getDeclaration(F->getParent(), Intrinsic::ctlz, IntTy);
+ Intrinsic::getOrInsertDeclaration(F->getParent(), Intrinsic::ctlz, IntTy);
ConstantInt *True = Builder.getTrue();
// entry:
diff --git a/llvm/lib/CodeGen/ExpandMemCmp.cpp b/llvm/lib/CodeGen/ExpandMemCmp.cpp
index 04222d5b4afd..6d626de0b4e6 100644
--- a/llvm/lib/CodeGen/ExpandMemCmp.cpp
+++ b/llvm/lib/CodeGen/ExpandMemCmp.cpp
@@ -355,7 +355,7 @@ MemCmpExpansion::LoadPair MemCmpExpansion::getLoadPair(Type *LoadSizeType,
// Swap bytes if required.
if (BSwapSizeType) {
- Function *Bswap = Intrinsic::getDeclaration(
+ Function *Bswap = Intrinsic::getOrInsertDeclaration(
CI->getModule(), Intrinsic::bswap, BSwapSizeType);
Lhs = Builder.CreateCall(Bswap, Lhs);
Rhs = Builder.CreateCall(Bswap, Rhs);
diff --git a/llvm/lib/CodeGen/ExpandVectorPredication.cpp b/llvm/lib/CodeGen/ExpandVectorPredication.cpp
index ffe879ff0496..32ba3e91822d 100644
--- a/llvm/lib/CodeGen/ExpandVectorPredication.cpp
+++ b/llvm/lib/CodeGen/ExpandVectorPredication.cpp
@@ -237,7 +237,7 @@ Value *CachingVPExpander::convertEVLToMask(IRBuilder<> &Builder,
if (ElemCount.isScalable()) {
auto *M = Builder.GetInsertBlock()->getModule();
Type *BoolVecTy = VectorType::get(Builder.getInt1Ty(), ElemCount);
- Function *ActiveMaskFunc = Intrinsic::getDeclaration(
+ Function *ActiveMaskFunc = Intrinsic::getOrInsertDeclaration(
M, Intrinsic::get_active_lane_mask, {BoolVecTy, EVLParam->getType()});
// `get_active_lane_mask` performs an implicit less-than comparison.
Value *ConstZero = Builder.getInt32(0);
@@ -299,7 +299,7 @@ Value *CachingVPExpander::expandPredicationToIntCall(
case Intrinsic::umin: {
Value *Op0 = VPI.getOperand(0);
Value *Op1 = VPI.getOperand(1);
- Function *Fn = Intrinsic::getDeclaration(
+ Function *Fn = Intrinsic::getOrInsertDeclaration(
VPI.getModule(), UnpredicatedIntrinsicID, {VPI.getType()});
Value *NewOp = Builder.CreateCall(Fn, {Op0, Op1}, VPI.getName());
replaceOperation(*NewOp, VPI);
@@ -308,7 +308,7 @@ Value *CachingVPExpander::expandPredicationToIntCall(
case Intrinsic::bswap:
case Intrinsic::bitreverse: {
Value *Op = VPI.getOperand(0);
- Function *Fn = Intrinsic::getDeclaration(
+ Function *Fn = Intrinsic::getOrInsertDeclaration(
VPI.getModule(), UnpredicatedIntrinsicID, {VPI.getType()});
Value *NewOp = Builder.CreateCall(Fn, {Op}, VPI.getName());
replaceOperation(*NewOp, VPI);
@@ -327,7 +327,7 @@ Value *CachingVPExpander::expandPredicationToFPCall(
case Intrinsic::fabs:
case Intrinsic::sqrt: {
Value *Op0 = VPI.getOperand(0);
- Function *Fn = Intrinsic::getDeclaration(
+ Function *Fn = Intrinsic::getOrInsertDeclaration(
VPI.getModule(), UnpredicatedIntrinsicID, {VPI.getType()});
Value *NewOp = Builder.CreateCall(Fn, {Op0}, VPI.getName());
replaceOperation(*NewOp, VPI);
@@ -337,7 +337,7 @@ Value *CachingVPExpander::expandPredicationToFPCall(
case Intrinsic::minnum: {
Value *Op0 = VPI.getOperand(0);
Value *Op1 = VPI.getOperand(1);
- Function *Fn = Intrinsic::getDeclaration(
+ Function *Fn = Intrinsic::getOrInsertDeclaration(
VPI.getModule(), UnpredicatedIntrinsicID, {VPI.getType()});
Value *NewOp = Builder.CreateCall(Fn, {Op0, Op1}, VPI.getName());
replaceOperation(*NewOp, VPI);
@@ -350,7 +350,7 @@ Value *CachingVPExpander::expandPredicationToFPCall(
Value *Op0 = VPI.getOperand(0);
Value *Op1 = VPI.getOperand(1);
Value *Op2 = VPI.getOperand(2);
- Function *Fn = Intrinsic::getDeclaration(
+ Function *Fn = Intrinsic::getOrInsertDeclaration(
VPI.getModule(), UnpredicatedIntrinsicID, {VPI.getType()});
Value *NewOp;
if (Intrinsic::isConstrainedFPIntrinsic(UnpredicatedIntrinsicID))
@@ -594,7 +594,7 @@ bool CachingVPExpander::discardEVLParameter(VPIntrinsic &VPI) {
// TODO add caching
auto *M = VPI.getModule();
Function *VScaleFunc =
- Intrinsic::getDeclaration(M, Intrinsic::vscale, Int32Ty);
+ Intrinsic::getOrInsertDeclaration(M, Intrinsic::vscale, Int32Ty);
IRBuilder<> Builder(VPI.getParent(), VPI.getIterator());
Value *FactorConst = Builder.getInt32(StaticElemCount.getKnownMinValue());
Value *VScale = Builder.CreateCall(VScaleFunc, {}, "vscale");
diff --git a/llvm/lib/CodeGen/HardwareLoops.cpp b/llvm/lib/CodeGen/HardwareLoops.cpp
index 9205eabcf568..c8a63304a3b6 100644
--- a/llvm/lib/CodeGen/HardwareLoops.cpp
+++ b/llvm/lib/CodeGen/HardwareLoops.cpp
@@ -512,7 +512,7 @@ Value* HardwareLoop::InsertIterationSetup(Value *LoopCountInit) {
: Intrinsic::test_set_loop_iterations)
: (UsePhi ? Intrinsic::start_loop_iterations
: Intrinsic::set_loop_iterations);
- Function *LoopIter = Intrinsic::getDeclaration(M, ID, Ty);
+ Function *LoopIter = Intrinsic::getOrInsertDeclaration(M, ID, Ty);
Value *LoopSetup = Builder.CreateCall(LoopIter, LoopCountInit);
// Use the return value of the intrinsic to control the entry of the loop.
@@ -541,9 +541,8 @@ void HardwareLoop::InsertLoopDec() {
Attribute::StrictFP))
CondBuilder.setIsFPConstrained(true);
- Function *DecFunc =
- Intrinsic::getDeclaration(M, Intrinsic::loop_decrement,
- LoopDecrement->getType());
+ Function *DecFunc = Intrinsic::getOrInsertDeclaration(
+ M, Intrinsic::loop_decrement, LoopDecrement->getType());
Value *Ops[] = { LoopDecrement };
Value *NewCond = CondBuilder.CreateCall(DecFunc, Ops);
Value *OldCond = ExitBranch->getCondition();
@@ -566,9 +565,8 @@ Instruction* HardwareLoop::InsertLoopRegDec(Value *EltsRem) {
Attribute::StrictFP))
CondBuilder.setIsFPConstrained(true);
- Function *DecFunc =
- Intrinsic::getDeclaration(M, Intrinsic::loop_decrement_reg,
- { EltsRem->getType() });
+ Function *DecFunc = Intrinsic::getOrInsertDeclaration(
+ M, Intrinsic::loop_decrement_reg, {EltsRem->getType()});
Value *Ops[] = { EltsRem, LoopDecrement };
Value *Call = CondBuilder.CreateCall(DecFunc, Ops);
diff --git a/llvm/lib/CodeGen/IntrinsicLowering.cpp b/llvm/lib/CodeGen/IntrinsicLowering.cpp
index 256c081b46e2..f799a8cfc1ba 100644
--- a/llvm/lib/CodeGen/IntrinsicLowering.cpp
+++ b/llvm/lib/CodeGen/IntrinsicLowering.cpp
@@ -474,7 +474,7 @@ bool IntrinsicLowering::LowerToByteSwap(CallInst *CI) {
// Okay, we can do this xform, do so now.
Module *M = CI->getModule();
- Function *Int = Intrinsic::getDeclaration(M, Intrinsic::bswap, Ty);
+ Function *Int = Intrinsic::getOrInsertDeclaration(M, Intrinsic::bswap, Ty);
Value *Op = CI->getArgOperand(0);
Op = CallInst::Create(Int, Op, CI->getName(), CI->getIterator());
diff --git a/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp b/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp
index 0c0a4e13c7c9..a2b166227194 100644
--- a/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp
+++ b/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp
@@ -102,14 +102,6 @@ LiveDebugValues::LiveDebugValues() : MachineFunctionPass(ID) {
}
bool LiveDebugValues::runOnMachineFunction(MachineFunction &MF) {
- // Except for Wasm, all targets should be only using physical register at this
- // point. Wasm only use virtual registers throught its pipeline, but its
- // virtual registers don't participate in this LiveDebugValues analysis; only
- // its target indices do.
- assert(MF.getTarget().getTargetTriple().isWasm() ||
- MF.getProperties().hasProperty(
- MachineFunctionProperties::Property::NoVRegs));
-
bool InstrRefBased = MF.useDebugInstrRef();
// Allow the user to force selection of InstrRef LDV.
InstrRefBased |= ForceInstrRefLDV;
diff --git a/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp
index 7e7d90f24fcc..c80b54a4f912 100644
--- a/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp
+++ b/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp
@@ -239,6 +239,10 @@ struct LocIndex {
/// becomes a problem.
static constexpr u32_location_t kWasmLocation = kFirstInvalidRegLocation + 2;
+ /// The first location that is reserved for VarLocs with locations of kind
+ /// VirtualRegisterKind.
+ static constexpr u32_location_t kFirstVirtualRegLocation = 1 << 31;
+
LocIndex(u32_location_t Location, u32_index_t Index)
: Location(Location), Index(Index) {}
@@ -810,9 +814,10 @@ private:
VL.getDescribingRegs(Locations);
assert(all_of(Locations,
[](auto RegNo) {
- return RegNo < LocIndex::kFirstInvalidRegLocation;
+ return (RegNo < LocIndex::kFirstInvalidRegLocation) ||
+ (LocIndex::kFirstVirtualRegLocation <= RegNo);
}) &&
- "Physreg out of range?");
+ "Physical or virtual register out of range?");
if (VL.containsSpillLocs())
Locations.push_back(LocIndex::kSpillLocation);
if (VL.containsWasmLocs())
@@ -1240,9 +1245,9 @@ void VarLocBasedLDV::getUsedRegs(const VarLocSet &CollectFrom,
LocIndex::rawIndexForReg(LocIndex::kFirstRegLocation);
uint64_t FirstInvalidIndex =
LocIndex::rawIndexForReg(LocIndex::kFirstInvalidRegLocation);
- for (auto It = CollectFrom.find(FirstRegIndex),
- End = CollectFrom.find(FirstInvalidIndex);
- It != End;) {
+ uint64_t FirstVirtualRegIndex =
+ LocIndex::rawIndexForReg(LocIndex::kFirstVirtualRegLocation);
+ auto doGetUsedRegs = [&](VarLocSet::const_iterator &It) {
// We found a VarLoc ID for a VarLoc that lives in a register. Figure out
// which register and add it to UsedRegs.
uint32_t FoundReg = LocIndex::fromRawInteger(*It).Location;
@@ -1255,6 +1260,16 @@ void VarLocBasedLDV::getUsedRegs(const VarLocSet &CollectFrom,
// guaranteed to move on to the next register (or to end()).
uint64_t NextRegIndex = LocIndex::rawIndexForReg(FoundReg + 1);
It.advanceToLowerBound(NextRegIndex);
+ };
+ for (auto It = CollectFrom.find(FirstRegIndex),
+ End = CollectFrom.find(FirstInvalidIndex);
+ It != End;) {
+ doGetUsedRegs(It);
+ }
+ for (auto It = CollectFrom.find(FirstVirtualRegIndex),
+ End = CollectFrom.end();
+ It != End;) {
+ doGetUsedRegs(It);
}
}
diff --git a/llvm/lib/CodeGen/MachineBlockPlacement.cpp b/llvm/lib/CodeGen/MachineBlockPlacement.cpp
index c42e63202c3b..dd5220b4599f 100644
--- a/llvm/lib/CodeGen/MachineBlockPlacement.cpp
+++ b/llvm/lib/CodeGen/MachineBlockPlacement.cpp
@@ -3572,7 +3572,7 @@ bool MachineBlockPlacement::runOnMachineFunction(MachineFunction &MF) {
if (UseExtTspForPerf || UseExtTspForSize) {
assert(
!(UseExtTspForPerf && UseExtTspForSize) &&
- "UseExtTspForPerf and UseExtTspForSize can not be set simultaneosly");
+ "UseExtTspForPerf and UseExtTspForSize can not be set simultaneously");
applyExtTsp(/*OptForSize=*/UseExtTspForSize);
createCFGChainExtTsp();
}
@@ -3745,11 +3745,6 @@ void MachineBlockPlacement::assignBlockOrder(
continue;
MBB.updateTerminator(FTMBB);
}
-
-#ifndef NDEBUG
- // Make sure we correctly constructed all branches.
- F->verify(this, "After optimized block reordering", &errs());
-#endif
}
void MachineBlockPlacement::createCFGChainExtTsp() {
diff --git a/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
index 8bcc437cbfb8..fb4da2c11cda 100644
--- a/llvm/lib/CodeGen/MachineCopyPropagation.cpp
+++ b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
@@ -886,8 +886,11 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
"MachineCopyPropagation should be run after register allocation!");
if (MO.isDef() && !MO.isEarlyClobber()) {
- Defs.push_back(Reg.asMCReg());
- continue;
+ // Skip invalidating constant registers.
+ if (!MRI->isConstantPhysReg(Reg)) {
+ Defs.push_back(Reg.asMCReg());
+ continue;
+ }
} else if (MO.readsReg())
ReadRegister(Reg.asMCReg(), MI, MO.isDebug() ? DebugUse : RegularUse);
}
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index 24a0f41775cc..e2c09fe25d55 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -77,8 +77,10 @@
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/ModRef.h"
+#include "llvm/Support/Mutex.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include <algorithm>
@@ -93,257 +95,300 @@ using namespace llvm;
namespace {
- struct MachineVerifier {
- MachineVerifier(MachineFunctionAnalysisManager &MFAM, const char *b,
- raw_ostream *OS)
- : MFAM(&MFAM), OS(OS ? *OS : nulls()), Banner(b) {}
-
- MachineVerifier(Pass *pass, const char *b, raw_ostream *OS)
- : PASS(pass), OS(OS ? *OS : nulls()), Banner(b) {}
-
- MachineVerifier(const char *b, LiveVariables *LiveVars,
- LiveIntervals *LiveInts, LiveStacks *LiveStks,
- SlotIndexes *Indexes, raw_ostream *OS)
- : OS(OS ? *OS : nulls()), Banner(b), LiveVars(LiveVars),
- LiveInts(LiveInts), LiveStks(LiveStks), Indexes(Indexes) {}
-
- unsigned verify(const MachineFunction &MF);
-
- MachineFunctionAnalysisManager *MFAM = nullptr;
- Pass *const PASS = nullptr;
- raw_ostream &OS;
- const char *Banner;
- const MachineFunction *MF = nullptr;
- const TargetMachine *TM = nullptr;
- const TargetInstrInfo *TII = nullptr;
- const TargetRegisterInfo *TRI = nullptr;
- const MachineRegisterInfo *MRI = nullptr;
- const RegisterBankInfo *RBI = nullptr;
-
- unsigned foundErrors = 0;
-
- // Avoid querying the MachineFunctionProperties for each operand.
- bool isFunctionRegBankSelected = false;
- bool isFunctionSelected = false;
- bool isFunctionTracksDebugUserValues = false;
-
- using RegVector = SmallVector<Register, 16>;
- using RegMaskVector = SmallVector<const uint32_t *, 4>;
- using RegSet = DenseSet<Register>;
- using RegMap = DenseMap<Register, const MachineInstr *>;
- using BlockSet = SmallPtrSet<const MachineBasicBlock *, 8>;
-
- const MachineInstr *FirstNonPHI = nullptr;
- const MachineInstr *FirstTerminator = nullptr;
- BlockSet FunctionBlocks;
-
- BitVector regsReserved;
- RegSet regsLive;
- RegVector regsDefined, regsDead, regsKilled;
- RegMaskVector regMasks;
-
- SlotIndex lastIndex;
-
- // Add Reg and any sub-registers to RV
- void addRegWithSubRegs(RegVector &RV, Register Reg) {
- RV.push_back(Reg);
- if (Reg.isPhysical())
- append_range(RV, TRI->subregs(Reg.asMCReg()));
- }
-
- struct BBInfo {
- // Is this MBB reachable from the MF entry point?
- bool reachable = false;
-
- // Vregs that must be live in because they are used without being
- // defined. Map value is the user. vregsLiveIn doesn't include regs
- // that only are used by PHI nodes.
- RegMap vregsLiveIn;
-
- // Regs killed in MBB. They may be defined again, and will then be in both
- // regsKilled and regsLiveOut.
- RegSet regsKilled;
-
- // Regs defined in MBB and live out. Note that vregs passing through may
- // be live out without being mentioned here.
- RegSet regsLiveOut;
-
- // Vregs that pass through MBB untouched. This set is disjoint from
- // regsKilled and regsLiveOut.
- RegSet vregsPassed;
-
- // Vregs that must pass through MBB because they are needed by a successor
- // block. This set is disjoint from regsLiveOut.
- RegSet vregsRequired;
-
- // Set versions of block's predecessor and successor lists.
- BlockSet Preds, Succs;
-
- BBInfo() = default;
-
- // Add register to vregsRequired if it belongs there. Return true if
- // anything changed.
- bool addRequired(Register Reg) {
- if (!Reg.isVirtual())
- return false;
- if (regsLiveOut.count(Reg))
- return false;
- return vregsRequired.insert(Reg).second;
- }
+/// Used the by the ReportedErrors class to guarantee only one error is reported
+/// at one time.
+static ManagedStatic<sys::SmartMutex<true>> ReportedErrorsLock;
+
+struct MachineVerifier {
+ MachineVerifier(MachineFunctionAnalysisManager &MFAM, const char *b,
+ raw_ostream *OS, bool AbortOnError = true)
+ : MFAM(&MFAM), OS(OS ? *OS : nulls()), Banner(b),
+ ReportedErrs(AbortOnError) {}
+
+ MachineVerifier(Pass *pass, const char *b, raw_ostream *OS,
+ bool AbortOnError = true)
+ : PASS(pass), OS(OS ? *OS : nulls()), Banner(b),
+ ReportedErrs(AbortOnError) {}
+
+ MachineVerifier(const char *b, LiveVariables *LiveVars,
+ LiveIntervals *LiveInts, LiveStacks *LiveStks,
+ SlotIndexes *Indexes, raw_ostream *OS,
+ bool AbortOnError = true)
+ : OS(OS ? *OS : nulls()), Banner(b), LiveVars(LiveVars),
+ LiveInts(LiveInts), LiveStks(LiveStks), Indexes(Indexes),
+ ReportedErrs(AbortOnError) {}
+
+ /// \returns true if no problems were found.
+ bool verify(const MachineFunction &MF);
+
+ MachineFunctionAnalysisManager *MFAM = nullptr;
+ Pass *const PASS = nullptr;
+ raw_ostream &OS;
+ const char *Banner;
+ const MachineFunction *MF = nullptr;
+ const TargetMachine *TM = nullptr;
+ const TargetInstrInfo *TII = nullptr;
+ const TargetRegisterInfo *TRI = nullptr;
+ const MachineRegisterInfo *MRI = nullptr;
+ const RegisterBankInfo *RBI = nullptr;
+
+ // Avoid querying the MachineFunctionProperties for each operand.
+ bool isFunctionRegBankSelected = false;
+ bool isFunctionSelected = false;
+ bool isFunctionTracksDebugUserValues = false;
+
+ using RegVector = SmallVector<Register, 16>;
+ using RegMaskVector = SmallVector<const uint32_t *, 4>;
+ using RegSet = DenseSet<Register>;
+ using RegMap = DenseMap<Register, const MachineInstr *>;
+ using BlockSet = SmallPtrSet<const MachineBasicBlock *, 8>;
+
+ const MachineInstr *FirstNonPHI = nullptr;
+ const MachineInstr *FirstTerminator = nullptr;
+ BlockSet FunctionBlocks;
+
+ BitVector regsReserved;
+ RegSet regsLive;
+ RegVector regsDefined, regsDead, regsKilled;
+ RegMaskVector regMasks;
+
+ SlotIndex lastIndex;
+
+ // Add Reg and any sub-registers to RV
+ void addRegWithSubRegs(RegVector &RV, Register Reg) {
+ RV.push_back(Reg);
+ if (Reg.isPhysical())
+ append_range(RV, TRI->subregs(Reg.asMCReg()));
+ }
+
+ struct BBInfo {
+ // Is this MBB reachable from the MF entry point?
+ bool reachable = false;
+
+ // Vregs that must be live in because they are used without being
+ // defined. Map value is the user. vregsLiveIn doesn't include regs
+ // that only are used by PHI nodes.
+ RegMap vregsLiveIn;
+
+ // Regs killed in MBB. They may be defined again, and will then be in both
+ // regsKilled and regsLiveOut.
+ RegSet regsKilled;
+
+ // Regs defined in MBB and live out. Note that vregs passing through may
+ // be live out without being mentioned here.
+ RegSet regsLiveOut;
+
+ // Vregs that pass through MBB untouched. This set is disjoint from
+ // regsKilled and regsLiveOut.
+ RegSet vregsPassed;
+
+ // Vregs that must pass through MBB because they are needed by a successor
+ // block. This set is disjoint from regsLiveOut.
+ RegSet vregsRequired;
+
+ // Set versions of block's predecessor and successor lists.
+ BlockSet Preds, Succs;
+
+ BBInfo() = default;
+
+ // Add register to vregsRequired if it belongs there. Return true if
+ // anything changed.
+ bool addRequired(Register Reg) {
+ if (!Reg.isVirtual())
+ return false;
+ if (regsLiveOut.count(Reg))
+ return false;
+ return vregsRequired.insert(Reg).second;
+ }
- // Same for a full set.
- bool addRequired(const RegSet &RS) {
- bool Changed = false;
- for (Register Reg : RS)
- Changed |= addRequired(Reg);
- return Changed;
- }
+ // Same for a full set.
+ bool addRequired(const RegSet &RS) {
+ bool Changed = false;
+ for (Register Reg : RS)
+ Changed |= addRequired(Reg);
+ return Changed;
+ }
- // Same for a full map.
- bool addRequired(const RegMap &RM) {
- bool Changed = false;
- for (const auto &I : RM)
- Changed |= addRequired(I.first);
- return Changed;
- }
+ // Same for a full map.
+ bool addRequired(const RegMap &RM) {
+ bool Changed = false;
+ for (const auto &I : RM)
+ Changed |= addRequired(I.first);
+ return Changed;
+ }
- // Live-out registers are either in regsLiveOut or vregsPassed.
- bool isLiveOut(Register Reg) const {
- return regsLiveOut.count(Reg) || vregsPassed.count(Reg);
- }
- };
+ // Live-out registers are either in regsLiveOut or vregsPassed.
+ bool isLiveOut(Register Reg) const {
+ return regsLiveOut.count(Reg) || vregsPassed.count(Reg);
+ }
+ };
- // Extra register info per MBB.
- DenseMap<const MachineBasicBlock*, BBInfo> MBBInfoMap;
-
- bool isReserved(Register Reg) {
- return Reg.id() < regsReserved.size() && regsReserved.test(Reg.id());
- }
-
- bool isAllocatable(Register Reg) const {
- return Reg.id() < TRI->getNumRegs() && TRI->isInAllocatableClass(Reg) &&
- !regsReserved.test(Reg.id());
- }
-
- // Analysis information if available
- LiveVariables *LiveVars = nullptr;
- LiveIntervals *LiveInts = nullptr;
- LiveStacks *LiveStks = nullptr;
- SlotIndexes *Indexes = nullptr;
-
- // This is calculated only when trying to verify convergence control tokens.
- // Similar to the LLVM IR verifier, we calculate this locally instead of
- // relying on the pass manager.
- MachineDominatorTree DT;
-
- void visitMachineFunctionBefore();
- void visitMachineBasicBlockBefore(const MachineBasicBlock *MBB);
- void visitMachineBundleBefore(const MachineInstr *MI);
-
- /// Verify that all of \p MI's virtual register operands are scalars.
- /// \returns True if all virtual register operands are scalar. False
- /// otherwise.
- bool verifyAllRegOpsScalar(const MachineInstr &MI,
- const MachineRegisterInfo &MRI);
- bool verifyVectorElementMatch(LLT Ty0, LLT Ty1, const MachineInstr *MI);
-
- bool verifyGIntrinsicSideEffects(const MachineInstr *MI);
- bool verifyGIntrinsicConvergence(const MachineInstr *MI);
- void verifyPreISelGenericInstruction(const MachineInstr *MI);
-
- void visitMachineInstrBefore(const MachineInstr *MI);
- void visitMachineOperand(const MachineOperand *MO, unsigned MONum);
- void visitMachineBundleAfter(const MachineInstr *MI);
- void visitMachineBasicBlockAfter(const MachineBasicBlock *MBB);
- void visitMachineFunctionAfter();
-
- void report(const char *msg, const MachineFunction *MF);
- void report(const char *msg, const MachineBasicBlock *MBB);
- void report(const char *msg, const MachineInstr *MI);
- void report(const char *msg, const MachineOperand *MO, unsigned MONum,
- LLT MOVRegType = LLT{});
- void report(const Twine &Msg, const MachineInstr *MI);
-
- void report_context(const LiveInterval &LI) const;
- void report_context(const LiveRange &LR, Register VRegUnit,
- LaneBitmask LaneMask) const;
- void report_context(const LiveRange::Segment &S) const;
- void report_context(const VNInfo &VNI) const;
- void report_context(SlotIndex Pos) const;
- void report_context(MCPhysReg PhysReg) const;
- void report_context_liverange(const LiveRange &LR) const;
- void report_context_lanemask(LaneBitmask LaneMask) const;
- void report_context_vreg(Register VReg) const;
- void report_context_vreg_regunit(Register VRegOrUnit) const;
-
- void verifyInlineAsm(const MachineInstr *MI);
-
- void checkLiveness(const MachineOperand *MO, unsigned MONum);
- void checkLivenessAtUse(const MachineOperand *MO, unsigned MONum,
- SlotIndex UseIdx, const LiveRange &LR,
- Register VRegOrUnit,
- LaneBitmask LaneMask = LaneBitmask::getNone());
- void checkLivenessAtDef(const MachineOperand *MO, unsigned MONum,
- SlotIndex DefIdx, const LiveRange &LR,
- Register VRegOrUnit, bool SubRangeCheck = false,
- LaneBitmask LaneMask = LaneBitmask::getNone());
-
- void markReachable(const MachineBasicBlock *MBB);
- void calcRegsPassed();
- void checkPHIOps(const MachineBasicBlock &MBB);
-
- void calcRegsRequired();
- void verifyLiveVariables();
- void verifyLiveIntervals();
- void verifyLiveInterval(const LiveInterval&);
- void verifyLiveRangeValue(const LiveRange &, const VNInfo *, Register,
- LaneBitmask);
- void verifyLiveRangeSegment(const LiveRange &,
- const LiveRange::const_iterator I, Register,
- LaneBitmask);
- void verifyLiveRange(const LiveRange &, Register,
- LaneBitmask LaneMask = LaneBitmask::getNone());
+ // Extra register info per MBB.
+ DenseMap<const MachineBasicBlock *, BBInfo> MBBInfoMap;
+
+ bool isReserved(Register Reg) {
+ return Reg.id() < regsReserved.size() && regsReserved.test(Reg.id());
+ }
+
+ bool isAllocatable(Register Reg) const {
+ return Reg.id() < TRI->getNumRegs() && TRI->isInAllocatableClass(Reg) &&
+ !regsReserved.test(Reg.id());
+ }
+
+ // Analysis information if available
+ LiveVariables *LiveVars = nullptr;
+ LiveIntervals *LiveInts = nullptr;
+ LiveStacks *LiveStks = nullptr;
+ SlotIndexes *Indexes = nullptr;
- void verifyStackFrame();
+ /// A class to track the number of reported error and to guarantee that only
+ /// one error is reported at one time.
+ class ReportedErrors {
+ unsigned NumReported = 0;
+ bool AbortOnError;
- void verifySlotIndexes() const;
- void verifyProperties(const MachineFunction &MF);
+ public:
+ /// \param AbortOnError -- If set, abort after printing the first error.
+ ReportedErrors(bool AbortOnError) : AbortOnError(AbortOnError) {}
+
+ ~ReportedErrors() {
+ if (!hasError())
+ return;
+ if (AbortOnError)
+ report_fatal_error("Found " + Twine(NumReported) +
+ " machine code errors.");
+ // Since we haven't aborted, release the lock to allow other threads to
+ // report errors.
+ ReportedErrorsLock->unlock();
+ }
+
+ /// Increment the number of reported errors.
+ /// \returns true if this is the first reported error.
+ bool increment() {
+ // If this is the first error this thread has encountered, grab the lock
+ // to prevent other threads from reporting errors at the same time.
+ // Otherwise we assume we already have the lock.
+ if (!hasError())
+ ReportedErrorsLock->lock();
+ ++NumReported;
+ return NumReported == 1;
+ }
+
+ /// \returns true if an error was reported.
+ bool hasError() { return NumReported; }
};
+ ReportedErrors ReportedErrs;
+
+ // This is calculated only when trying to verify convergence control tokens.
+ // Similar to the LLVM IR verifier, we calculate this locally instead of
+ // relying on the pass manager.
+ MachineDominatorTree DT;
+
+ void visitMachineFunctionBefore();
+ void visitMachineBasicBlockBefore(const MachineBasicBlock *MBB);
+ void visitMachineBundleBefore(const MachineInstr *MI);
+
+ /// Verify that all of \p MI's virtual register operands are scalars.
+ /// \returns True if all virtual register operands are scalar. False
+ /// otherwise.
+ bool verifyAllRegOpsScalar(const MachineInstr &MI,
+ const MachineRegisterInfo &MRI);
+ bool verifyVectorElementMatch(LLT Ty0, LLT Ty1, const MachineInstr *MI);
+
+ bool verifyGIntrinsicSideEffects(const MachineInstr *MI);
+ bool verifyGIntrinsicConvergence(const MachineInstr *MI);
+ void verifyPreISelGenericInstruction(const MachineInstr *MI);
+
+ void visitMachineInstrBefore(const MachineInstr *MI);
+ void visitMachineOperand(const MachineOperand *MO, unsigned MONum);
+ void visitMachineBundleAfter(const MachineInstr *MI);
+ void visitMachineBasicBlockAfter(const MachineBasicBlock *MBB);
+ void visitMachineFunctionAfter();
+
+ void report(const char *msg, const MachineFunction *MF);
+ void report(const char *msg, const MachineBasicBlock *MBB);
+ void report(const char *msg, const MachineInstr *MI);
+ void report(const char *msg, const MachineOperand *MO, unsigned MONum,
+ LLT MOVRegType = LLT{});
+ void report(const Twine &Msg, const MachineInstr *MI);
+
+ void report_context(const LiveInterval &LI) const;
+ void report_context(const LiveRange &LR, Register VRegUnit,
+ LaneBitmask LaneMask) const;
+ void report_context(const LiveRange::Segment &S) const;
+ void report_context(const VNInfo &VNI) const;
+ void report_context(SlotIndex Pos) const;
+ void report_context(MCPhysReg PhysReg) const;
+ void report_context_liverange(const LiveRange &LR) const;
+ void report_context_lanemask(LaneBitmask LaneMask) const;
+ void report_context_vreg(Register VReg) const;
+ void report_context_vreg_regunit(Register VRegOrUnit) const;
+
+ void verifyInlineAsm(const MachineInstr *MI);
+
+ void checkLiveness(const MachineOperand *MO, unsigned MONum);
+ void checkLivenessAtUse(const MachineOperand *MO, unsigned MONum,
+ SlotIndex UseIdx, const LiveRange &LR,
+ Register VRegOrUnit,
+ LaneBitmask LaneMask = LaneBitmask::getNone());
+ void checkLivenessAtDef(const MachineOperand *MO, unsigned MONum,
+ SlotIndex DefIdx, const LiveRange &LR,
+ Register VRegOrUnit, bool SubRangeCheck = false,
+ LaneBitmask LaneMask = LaneBitmask::getNone());
+
+ void markReachable(const MachineBasicBlock *MBB);
+ void calcRegsPassed();
+ void checkPHIOps(const MachineBasicBlock &MBB);
+
+ void calcRegsRequired();
+ void verifyLiveVariables();
+ void verifyLiveIntervals();
+ void verifyLiveInterval(const LiveInterval &);
+ void verifyLiveRangeValue(const LiveRange &, const VNInfo *, Register,
+ LaneBitmask);
+ void verifyLiveRangeSegment(const LiveRange &,
+ const LiveRange::const_iterator I, Register,
+ LaneBitmask);
+ void verifyLiveRange(const LiveRange &, Register,
+ LaneBitmask LaneMask = LaneBitmask::getNone());
- struct MachineVerifierLegacyPass : public MachineFunctionPass {
- static char ID; // Pass ID, replacement for typeid
+ void verifyStackFrame();
- const std::string Banner;
+ void verifySlotIndexes() const;
+ void verifyProperties(const MachineFunction &MF);
+};
- MachineVerifierLegacyPass(std::string banner = std::string())
- : MachineFunctionPass(ID), Banner(std::move(banner)) {
- initializeMachineVerifierLegacyPassPass(*PassRegistry::getPassRegistry());
- }
+struct MachineVerifierLegacyPass : public MachineFunctionPass {
+ static char ID; // Pass ID, replacement for typeid
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addUsedIfAvailable<LiveStacks>();
- AU.addUsedIfAvailable<LiveVariablesWrapperPass>();
- AU.addUsedIfAvailable<SlotIndexesWrapperPass>();
- AU.addUsedIfAvailable<LiveIntervalsWrapperPass>();
- AU.setPreservesAll();
- MachineFunctionPass::getAnalysisUsage(AU);
- }
+ const std::string Banner;
- bool runOnMachineFunction(MachineFunction &MF) override {
- // Skip functions that have known verification problems.
- // FIXME: Remove this mechanism when all problematic passes have been
- // fixed.
- if (MF.getProperties().hasProperty(
- MachineFunctionProperties::Property::FailsVerification))
- return false;
+ MachineVerifierLegacyPass(std::string banner = std::string())
+ : MachineFunctionPass(ID), Banner(std::move(banner)) {
+ initializeMachineVerifierLegacyPassPass(*PassRegistry::getPassRegistry());
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addUsedIfAvailable<LiveStacks>();
+ AU.addUsedIfAvailable<LiveVariablesWrapperPass>();
+ AU.addUsedIfAvailable<SlotIndexesWrapperPass>();
+ AU.addUsedIfAvailable<LiveIntervalsWrapperPass>();
+ AU.setPreservesAll();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
- unsigned FoundErrors =
- MachineVerifier(this, Banner.c_str(), &errs()).verify(MF);
- if (FoundErrors)
- report_fatal_error("Found "+Twine(FoundErrors)+" machine code errors.");
+ bool runOnMachineFunction(MachineFunction &MF) override {
+ // Skip functions that have known verification problems.
+ // FIXME: Remove this mechanism when all problematic passes have been
+ // fixed.
+ if (MF.getProperties().hasProperty(
+ MachineFunctionProperties::Property::FailsVerification))
return false;
- }
- };
+
+ MachineVerifier(this, Banner.c_str(), &errs()).verify(MF);
+ return false;
+ }
+};
} // end anonymous namespace
@@ -356,10 +401,7 @@ MachineVerifierPass::run(MachineFunction &MF,
if (MF.getProperties().hasProperty(
MachineFunctionProperties::Property::FailsVerification))
return PreservedAnalyses::all();
- unsigned FoundErrors =
- MachineVerifier(MFAM, Banner.c_str(), &errs()).verify(MF);
- if (FoundErrors)
- report_fatal_error("Found " + Twine(FoundErrors) + " machine code errors.");
+ MachineVerifier(MFAM, Banner.c_str(), &errs()).verify(MF);
return PreservedAnalyses::all();
}
@@ -379,31 +421,20 @@ void llvm::verifyMachineFunction(const std::string &Banner,
// LiveIntervals *LiveInts;
// LiveStacks *LiveStks;
// SlotIndexes *Indexes;
- unsigned FoundErrors =
- MachineVerifier(nullptr, Banner.c_str(), &errs()).verify(MF);
- if (FoundErrors)
- report_fatal_error("Found " + Twine(FoundErrors) + " machine code errors.");
+ MachineVerifier(nullptr, Banner.c_str(), &errs()).verify(MF);
}
bool MachineFunction::verify(Pass *p, const char *Banner, raw_ostream *OS,
- bool AbortOnErrors) const {
- MachineFunction &MF = const_cast<MachineFunction&>(*this);
- unsigned FoundErrors = MachineVerifier(p, Banner, OS).verify(MF);
- if (AbortOnErrors && FoundErrors)
- report_fatal_error("Found "+Twine(FoundErrors)+" machine code errors.");
- return FoundErrors == 0;
+ bool AbortOnError) const {
+ return MachineVerifier(p, Banner, OS, AbortOnError).verify(*this);
}
bool MachineFunction::verify(LiveIntervals *LiveInts, SlotIndexes *Indexes,
const char *Banner, raw_ostream *OS,
- bool AbortOnErrors) const {
- MachineFunction &MF = const_cast<MachineFunction &>(*this);
- unsigned FoundErrors =
- MachineVerifier(Banner, nullptr, LiveInts, nullptr, Indexes, OS)
- .verify(MF);
- if (AbortOnErrors && FoundErrors)
- report_fatal_error("Found " + Twine(FoundErrors) + " machine code errors.");
- return FoundErrors == 0;
+ bool AbortOnError) const {
+ return MachineVerifier(Banner, /*LiveVars=*/nullptr, LiveInts,
+ /*LiveStks=*/nullptr, Indexes, OS, AbortOnError)
+ .verify(*this);
}
void MachineVerifier::verifySlotIndexes() const {
@@ -429,9 +460,7 @@ void MachineVerifier::verifyProperties(const MachineFunction &MF) {
report("Function has NoVRegs property but there are VReg operands", &MF);
}
-unsigned MachineVerifier::verify(const MachineFunction &MF) {
- foundErrors = 0;
-
+bool MachineVerifier::verify(const MachineFunction &MF) {
this->MF = &MF;
TM = &MF.getTarget();
TII = MF.getSubtarget().getInstrInfo();
@@ -446,7 +475,7 @@ unsigned MachineVerifier::verify(const MachineFunction &MF) {
// it's expected that the MIR is somewhat broken but that's ok since we'll
// reset it and clear the FailedISel attribute in ResetMachineFunctions.
if (isFunctionFailedISel)
- return foundErrors;
+ return true;
isFunctionRegBankSelected = MF.getProperties().hasProperty(
MachineFunctionProperties::Property::RegBankSelected);
@@ -543,13 +572,13 @@ unsigned MachineVerifier::verify(const MachineFunction &MF) {
regMasks.clear();
MBBInfoMap.clear();
- return foundErrors;
+ return !ReportedErrs.hasError();
}
void MachineVerifier::report(const char *msg, const MachineFunction *MF) {
assert(MF);
OS << '\n';
- if (!foundErrors++) {
+ if (ReportedErrs.increment()) {
if (Banner)
OS << "# " << Banner << '\n';
@@ -3846,18 +3875,18 @@ namespace {
// integer, we can't tell whether it is a FrameSetup or FrameDestroy if the
// value is zero.
// We use a bool plus an integer to capture the stack state.
- struct StackStateOfBB {
- StackStateOfBB() = default;
- StackStateOfBB(int EntryVal, int ExitVal, bool EntrySetup, bool ExitSetup) :
- EntryValue(EntryVal), ExitValue(ExitVal), EntryIsSetup(EntrySetup),
- ExitIsSetup(ExitSetup) {}
-
- // Can be negative, which means we are setting up a frame.
- int EntryValue = 0;
- int ExitValue = 0;
- bool EntryIsSetup = false;
- bool ExitIsSetup = false;
- };
+struct StackStateOfBB {
+ StackStateOfBB() = default;
+ StackStateOfBB(int EntryVal, int ExitVal, bool EntrySetup, bool ExitSetup)
+ : EntryValue(EntryVal), ExitValue(ExitVal), EntryIsSetup(EntrySetup),
+ ExitIsSetup(ExitSetup) {}
+
+ // Can be negative, which means we are setting up a frame.
+ int EntryValue = 0;
+ int ExitValue = 0;
+ bool EntryIsSetup = false;
+ bool ExitIsSetup = false;
+};
} // end anonymous namespace
diff --git a/llvm/lib/CodeGen/ReplaceWithVeclib.cpp b/llvm/lib/CodeGen/ReplaceWithVeclib.cpp
index 9fbb7b461364..7f3c5cf6cb44 100644
--- a/llvm/lib/CodeGen/ReplaceWithVeclib.cpp
+++ b/llvm/lib/CodeGen/ReplaceWithVeclib.cpp
@@ -100,20 +100,34 @@ static void replaceWithTLIFunction(IntrinsicInst *II, VFInfo &Info,
static bool replaceWithCallToVeclib(const TargetLibraryInfo &TLI,
IntrinsicInst *II) {
assert(II != nullptr && "Intrinsic cannot be null");
+ Intrinsic::ID IID = II->getIntrinsicID();
+ Type *RetTy = II->getType();
+ Type *ScalarRetTy = RetTy->getScalarType();
// At the moment VFABI assumes the return type is always widened unless it is
// a void type.
- auto *VTy = dyn_cast<VectorType>(II->getType());
+ auto *VTy = dyn_cast<VectorType>(RetTy);
ElementCount EC(VTy ? VTy->getElementCount() : ElementCount::getFixed(0));
+
+ // OloadTys collects types used in scalar intrinsic overload name.
+ SmallVector<Type *, 3> OloadTys;
+ if (!RetTy->isVoidTy() && isVectorIntrinsicWithOverloadTypeAtArg(IID, -1))
+ OloadTys.push_back(ScalarRetTy);
+
// Compute the argument types of the corresponding scalar call and check that
// all vector operands match the previously found EC.
SmallVector<Type *, 8> ScalarArgTypes;
- Intrinsic::ID IID = II->getIntrinsicID();
for (auto Arg : enumerate(II->args())) {
auto *ArgTy = Arg.value()->getType();
+ bool IsOloadTy = isVectorIntrinsicWithOverloadTypeAtArg(IID, Arg.index());
if (isVectorIntrinsicWithScalarOpAtArg(IID, Arg.index())) {
ScalarArgTypes.push_back(ArgTy);
+ if (IsOloadTy)
+ OloadTys.push_back(ArgTy);
} else if (auto *VectorArgTy = dyn_cast<VectorType>(ArgTy)) {
- ScalarArgTypes.push_back(VectorArgTy->getElementType());
+ auto *ScalarArgTy = VectorArgTy->getElementType();
+ ScalarArgTypes.push_back(ScalarArgTy);
+ if (IsOloadTy)
+ OloadTys.push_back(ScalarArgTy);
// When return type is void, set EC to the first vector argument, and
// disallow vector arguments with different ECs.
if (EC.isZero())
@@ -129,7 +143,7 @@ static bool replaceWithCallToVeclib(const TargetLibraryInfo &TLI,
// using scalar argument types.
std::string ScalarName =
Intrinsic::isOverloaded(IID)
- ? Intrinsic::getName(IID, ScalarArgTypes, II->getModule())
+ ? Intrinsic::getName(IID, OloadTys, II->getModule())
: Intrinsic::getName(IID).str();
// Try to find the mapping for the scalar version of this intrinsic and the
@@ -146,7 +160,6 @@ static bool replaceWithCallToVeclib(const TargetLibraryInfo &TLI,
// Replace the call to the intrinsic with a call to the vector library
// function.
- Type *ScalarRetTy = II->getType()->getScalarType();
FunctionType *ScalarFTy =
FunctionType::get(ScalarRetTy, ScalarArgTypes, /*isVarArg*/ false);
const std::string MangledName = VD->getVectorFunctionABIVariantString();
@@ -193,6 +206,8 @@ static bool runImpl(const TargetLibraryInfo &TLI, Function &F) {
for (auto &I : instructions(F)) {
// Process only intrinsic calls that return void or a vector.
if (auto *II = dyn_cast<IntrinsicInst>(&I)) {
+ if (II->getIntrinsicID() == Intrinsic::not_intrinsic)
+ continue;
if (!II->getType()->isVectorTy() && !II->getType()->isVoidTy())
continue;
diff --git a/llvm/lib/CodeGen/SafeStack.cpp b/llvm/lib/CodeGen/SafeStack.cpp
index e41d1bfb0e53..a50909af8bfc 100644
--- a/llvm/lib/CodeGen/SafeStack.cpp
+++ b/llvm/lib/CodeGen/SafeStack.cpp
@@ -368,7 +368,8 @@ Value *SafeStack::getStackGuard(IRBuilder<> &IRB, Function &F) {
if (!StackGuardVar) {
TL.insertSSPDeclarations(*M);
- return IRB.CreateCall(Intrinsic::getDeclaration(M, Intrinsic::stackguard));
+ return IRB.CreateCall(
+ Intrinsic::getOrInsertDeclaration(M, Intrinsic::stackguard));
}
return IRB.CreateLoad(StackPtrTy, StackGuardVar, "StackGuard");
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index c6f6fc250805..810ca458bc87 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -11639,6 +11639,7 @@ static SDValue foldVSelectToSignBitSplatMask(SDNode *N, SelectionDAG &DAG) {
SDValue N1 = N->getOperand(1);
SDValue N2 = N->getOperand(2);
EVT VT = N->getValueType(0);
+ unsigned EltSizeInBits = VT.getScalarSizeInBits();
SDValue Cond0, Cond1;
ISD::CondCode CC;
@@ -11659,7 +11660,7 @@ static SDValue foldVSelectToSignBitSplatMask(SDNode *N, SelectionDAG &DAG) {
// (Cond0 s< 0) ? N1 : 0 --> (Cond0 s>> BW-1) & freeze(N1)
if (isNullOrNullSplat(N2)) {
SDLoc DL(N);
- SDValue ShiftAmt = DAG.getConstant(VT.getScalarSizeInBits() - 1, DL, VT);
+ SDValue ShiftAmt = DAG.getShiftAmountConstant(EltSizeInBits - 1, VT, DL);
SDValue Sra = DAG.getNode(ISD::SRA, DL, VT, Cond0, ShiftAmt);
return DAG.getNode(ISD::AND, DL, VT, Sra, DAG.getFreeze(N1));
}
@@ -11667,7 +11668,7 @@ static SDValue foldVSelectToSignBitSplatMask(SDNode *N, SelectionDAG &DAG) {
// (Cond0 s< 0) ? -1 : N2 --> (Cond0 s>> BW-1) | freeze(N2)
if (isAllOnesOrAllOnesSplat(N1)) {
SDLoc DL(N);
- SDValue ShiftAmt = DAG.getConstant(VT.getScalarSizeInBits() - 1, DL, VT);
+ SDValue ShiftAmt = DAG.getShiftAmountConstant(EltSizeInBits - 1, VT, DL);
SDValue Sra = DAG.getNode(ISD::SRA, DL, VT, Cond0, ShiftAmt);
return DAG.getNode(ISD::OR, DL, VT, Sra, DAG.getFreeze(N2));
}
@@ -11678,7 +11679,7 @@ static SDValue foldVSelectToSignBitSplatMask(SDNode *N, SelectionDAG &DAG) {
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
if (isNullOrNullSplat(N1) && TLI.hasAndNot(N1)) {
SDLoc DL(N);
- SDValue ShiftAmt = DAG.getConstant(VT.getScalarSizeInBits() - 1, DL, VT);
+ SDValue ShiftAmt = DAG.getShiftAmountConstant(EltSizeInBits - 1, VT, DL);
SDValue Sra = DAG.getNode(ISD::SRA, DL, VT, Cond0, ShiftAmt);
SDValue Not = DAG.getNOT(DL, Sra, VT);
return DAG.getNode(ISD::AND, DL, VT, Not, DAG.getFreeze(N2));
@@ -20321,13 +20322,11 @@ SDValue DAGCombiner::TransformFPLoadStorePair(SDNode *N) {
!FastLD || !FastST)
return SDValue();
- SDValue NewLD =
- DAG.getLoad(IntVT, SDLoc(Value), LD->getChain(), LD->getBasePtr(),
- LD->getPointerInfo(), LD->getAlign());
+ SDValue NewLD = DAG.getLoad(IntVT, SDLoc(Value), LD->getChain(),
+ LD->getBasePtr(), LD->getMemOperand());
- SDValue NewST =
- DAG.getStore(ST->getChain(), SDLoc(N), NewLD, ST->getBasePtr(),
- ST->getPointerInfo(), ST->getAlign());
+ SDValue NewST = DAG.getStore(ST->getChain(), SDLoc(N), NewLD,
+ ST->getBasePtr(), ST->getMemOperand());
AddToWorklist(NewLD.getNode());
AddToWorklist(NewST.getNode());
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 42d031310d5e..ea22b4670d6f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -1657,7 +1657,8 @@ SDValue SelectionDAGLegalize::ExpandFCOPYSIGN(SDNode *Node) const {
SDValue SignBit = DAG.getNode(ISD::AND, DL, IntVT, SignAsInt.IntValue,
SignMask);
- // If FABS is legal transform FCOPYSIGN(x, y) => sign(x) ? -FABS(x) : FABS(X)
+ // If FABS is legal transform
+ // FCOPYSIGN(x, y) => SignBit(y) ? -FABS(x) : FABS(x)
EVT FloatVT = Mag.getValueType();
if (TLI.isOperationLegalOrCustom(ISD::FABS, FloatVT) &&
TLI.isOperationLegalOrCustom(ISD::FNEG, FloatVT)) {
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index ab734ffb25db..9674de773883 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -1287,6 +1287,8 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
case ISD::VP_FMINIMUM:
case ISD::FMAXIMUM:
case ISD::VP_FMAXIMUM:
+ case ISD::FMINIMUMNUM:
+ case ISD::FMAXIMUMNUM:
case ISD::SDIV: case ISD::VP_SDIV:
case ISD::UDIV: case ISD::VP_UDIV:
case ISD::FDIV: case ISD::VP_FDIV:
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 25213f587116..a981e9cc7928 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -4386,6 +4386,15 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
// it.
IdxN = DAG.getSExtOrTrunc(IdxN, dl, N.getValueType());
+ SDNodeFlags ScaleFlags;
+ // The multiplication of an index by the type size does not wrap the
+ // pointer index type in a signed sense (mul nsw).
+ ScaleFlags.setNoSignedWrap(NW.hasNoUnsignedSignedWrap());
+
+ // The multiplication of an index by the type size does not wrap the
+ // pointer index type in an unsigned sense (mul nuw).
+ ScaleFlags.setNoUnsignedWrap(NW.hasNoUnsignedWrap());
+
if (ElementScalable) {
EVT VScaleTy = N.getValueType().getScalarType();
SDValue VScale = DAG.getNode(
@@ -4393,27 +4402,34 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
DAG.getConstant(ElementMul.getZExtValue(), dl, VScaleTy));
if (IsVectorGEP)
VScale = DAG.getSplatVector(N.getValueType(), dl, VScale);
- IdxN = DAG.getNode(ISD::MUL, dl, N.getValueType(), IdxN, VScale);
+ IdxN = DAG.getNode(ISD::MUL, dl, N.getValueType(), IdxN, VScale,
+ ScaleFlags);
} else {
// If this is a multiply by a power of two, turn it into a shl
// immediately. This is a very common case.
if (ElementMul != 1) {
if (ElementMul.isPowerOf2()) {
unsigned Amt = ElementMul.logBase2();
- IdxN = DAG.getNode(ISD::SHL, dl,
- N.getValueType(), IdxN,
- DAG.getConstant(Amt, dl, IdxN.getValueType()));
+ IdxN = DAG.getNode(ISD::SHL, dl, N.getValueType(), IdxN,
+ DAG.getConstant(Amt, dl, IdxN.getValueType()),
+ ScaleFlags);
} else {
SDValue Scale = DAG.getConstant(ElementMul.getZExtValue(), dl,
IdxN.getValueType());
- IdxN = DAG.getNode(ISD::MUL, dl,
- N.getValueType(), IdxN, Scale);
+ IdxN = DAG.getNode(ISD::MUL, dl, N.getValueType(), IdxN, Scale,
+ ScaleFlags);
}
}
}
- N = DAG.getNode(ISD::ADD, dl,
- N.getValueType(), N, IdxN);
+ // The successive addition of the current address, truncated to the
+ // pointer index type and interpreted as an unsigned number, and each
+ // offset, also interpreted as an unsigned number, does not wrap the
+ // pointer index type (add nuw).
+ SDNodeFlags AddFlags;
+ AddFlags.setNoUnsignedWrap(NW.hasNoUnsignedWrap());
+
+ N = DAG.getNode(ISD::ADD, dl, N.getValueType(), N, IdxN, AddFlags);
}
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 9df0f0adcc1e..793b8ff164c2 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -8424,6 +8424,11 @@ TargetLowering::createSelectForFMINNUM_FMAXNUM(SDNode *Node,
if (Node->getFlags().hasNoNaNs()) {
ISD::CondCode Pred = Opcode == ISD::FMINNUM ? ISD::SETLT : ISD::SETGT;
+ EVT VT = Node->getValueType(0);
+ if ((!isCondCodeLegal(Pred, VT.getSimpleVT()) ||
+ !isOperationLegalOrCustom(ISD::VSELECT, VT)) &&
+ VT.isVector())
+ return SDValue();
SDValue Op1 = Node->getOperand(0);
SDValue Op2 = Node->getOperand(1);
SDValue SelCC = DAG.getSelectCC(SDLoc(Node), Op1, Op2, Op1, Op2, Pred);
diff --git a/llvm/lib/CodeGen/SjLjEHPrepare.cpp b/llvm/lib/CodeGen/SjLjEHPrepare.cpp
index 054f7d721596..c4ad9f0b2172 100644
--- a/llvm/lib/CodeGen/SjLjEHPrepare.cpp
+++ b/llvm/lib/CodeGen/SjLjEHPrepare.cpp
@@ -508,17 +508,19 @@ bool SjLjEHPrepareImpl::runOnFunction(Function &F) {
PointerType *AllocaPtrTy = M.getDataLayout().getAllocaPtrType(M.getContext());
- FrameAddrFn =
- Intrinsic::getDeclaration(&M, Intrinsic::frameaddress, {AllocaPtrTy});
- StackAddrFn =
- Intrinsic::getDeclaration(&M, Intrinsic::stacksave, {AllocaPtrTy});
- StackRestoreFn =
- Intrinsic::getDeclaration(&M, Intrinsic::stackrestore, {AllocaPtrTy});
+ FrameAddrFn = Intrinsic::getOrInsertDeclaration(&M, Intrinsic::frameaddress,
+ {AllocaPtrTy});
+ StackAddrFn = Intrinsic::getOrInsertDeclaration(&M, Intrinsic::stacksave,
+ {AllocaPtrTy});
+ StackRestoreFn = Intrinsic::getOrInsertDeclaration(
+ &M, Intrinsic::stackrestore, {AllocaPtrTy});
BuiltinSetupDispatchFn =
- Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_setup_dispatch);
- LSDAAddrFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_lsda);
- CallSiteFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_callsite);
- FuncCtxFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_functioncontext);
+ Intrinsic::getOrInsertDeclaration(&M, Intrinsic::eh_sjlj_setup_dispatch);
+ LSDAAddrFn = Intrinsic::getOrInsertDeclaration(&M, Intrinsic::eh_sjlj_lsda);
+ CallSiteFn =
+ Intrinsic::getOrInsertDeclaration(&M, Intrinsic::eh_sjlj_callsite);
+ FuncCtxFn =
+ Intrinsic::getOrInsertDeclaration(&M, Intrinsic::eh_sjlj_functioncontext);
bool Res = setupEntryBlockAndCallSites(F);
return Res;
diff --git a/llvm/lib/CodeGen/StackProtector.cpp b/llvm/lib/CodeGen/StackProtector.cpp
index 1f23838b2de0..a192161bbd94 100644
--- a/llvm/lib/CodeGen/StackProtector.cpp
+++ b/llvm/lib/CodeGen/StackProtector.cpp
@@ -519,7 +519,8 @@ static Value *getStackGuard(const TargetLoweringBase *TLI, Module *M,
if (SupportsSelectionDAGSP)
*SupportsSelectionDAGSP = true;
TLI->insertSSPDeclarations(*M);
- return B.CreateCall(Intrinsic::getDeclaration(M, Intrinsic::stackguard));
+ return B.CreateCall(
+ Intrinsic::getOrInsertDeclaration(M, Intrinsic::stackguard));
}
/// Insert code into the entry block that stores the stack guard
@@ -540,7 +541,7 @@ static bool CreatePrologue(Function *F, Module *M, Instruction *CheckLoc,
AI = B.CreateAlloca(PtrTy, nullptr, "StackGuardSlot");
Value *GuardSlot = getStackGuard(TLI, M, B, &SupportsSelectionDAGSP);
- B.CreateCall(Intrinsic::getDeclaration(M, Intrinsic::stackprotector),
+ B.CreateCall(Intrinsic::getOrInsertDeclaration(M, Intrinsic::stackprotector),
{GuardSlot, AI});
return SupportsSelectionDAGSP;
}
diff --git a/llvm/lib/CodeGen/WasmEHPrepare.cpp b/llvm/lib/CodeGen/WasmEHPrepare.cpp
index 7514d49fb18a..1701b0d04425 100644
--- a/llvm/lib/CodeGen/WasmEHPrepare.cpp
+++ b/llvm/lib/CodeGen/WasmEHPrepare.cpp
@@ -196,7 +196,7 @@ bool WasmEHPrepareImpl::prepareThrows(Function &F) {
bool Changed = false;
// wasm.throw() intinsic, which will be lowered to wasm 'throw' instruction.
- ThrowF = Intrinsic::getDeclaration(&M, Intrinsic::wasm_throw);
+ ThrowF = Intrinsic::getOrInsertDeclaration(&M, Intrinsic::wasm_throw);
// Insert an unreachable instruction after a call to @llvm.wasm.throw and
// delete all following instructions within the BB, and delete all the dead
// children of the BB as well.
@@ -260,18 +260,21 @@ bool WasmEHPrepareImpl::prepareEHPads(Function &F) {
0, 2, "selector_gep");
// wasm.landingpad.index() intrinsic, which is to specify landingpad index
- LPadIndexF = Intrinsic::getDeclaration(&M, Intrinsic::wasm_landingpad_index);
+ LPadIndexF =
+ Intrinsic::getOrInsertDeclaration(&M, Intrinsic::wasm_landingpad_index);
// wasm.lsda() intrinsic. Returns the address of LSDA table for the current
// function.
- LSDAF = Intrinsic::getDeclaration(&M, Intrinsic::wasm_lsda);
+ LSDAF = Intrinsic::getOrInsertDeclaration(&M, Intrinsic::wasm_lsda);
// wasm.get.exception() and wasm.get.ehselector() intrinsics. Calls to these
// are generated in clang.
- GetExnF = Intrinsic::getDeclaration(&M, Intrinsic::wasm_get_exception);
- GetSelectorF = Intrinsic::getDeclaration(&M, Intrinsic::wasm_get_ehselector);
+ GetExnF =
+ Intrinsic::getOrInsertDeclaration(&M, Intrinsic::wasm_get_exception);
+ GetSelectorF =
+ Intrinsic::getOrInsertDeclaration(&M, Intrinsic::wasm_get_ehselector);
// wasm.catch() will be lowered down to wasm 'catch' instruction in
// instruction selection.
- CatchF = Intrinsic::getDeclaration(&M, Intrinsic::wasm_catch);
+ CatchF = Intrinsic::getOrInsertDeclaration(&M, Intrinsic::wasm_catch);
// _Unwind_CallPersonality() wrapper function, which calls the personality
CallPersonalityF = M.getOrInsertFunction("_Unwind_CallPersonality",