[llvm] [Windows SEH] fix failed assert and crash (PR #107031)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 2 17:41:59 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-selectiondag
Author: None (R-Goc)
<details>
<summary>Changes</summary>
Fixes https://github.com/llvm/llvm-project/issues/105813 and https://github.com/llvm/llvm-project/issues/106915.
Adds a check for the end of the iterator, which can be a sentinel.
---
Patch is 53.70 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/107031.diff
1 Files Affected:
- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (+300-265)
``````````diff
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index b37e54d66ddf51..22a4cb04d717ef 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -121,7 +121,8 @@ STATISTIC(NumFastIselFailures, "Number of instructions fast isel failed on");
STATISTIC(NumFastIselSuccess, "Number of instructions fast isel selected");
STATISTIC(NumFastIselBlocks, "Number of blocks selected entirely by fast isel");
STATISTIC(NumDAGBlocks, "Number of blocks selected using DAG");
-STATISTIC(NumDAGIselRetries,"Number of times dag isel has to try another path");
+STATISTIC(NumDAGIselRetries,
+ "Number of times dag isel has to try another path");
STATISTIC(NumEntryBlocks, "Number of entry blocks encountered");
STATISTIC(NumFastIselFailLowerArguments,
"Number of entry blocks where fast isel failed to lower arguments");
@@ -139,23 +140,22 @@ static cl::opt<bool> EnableFastISelFallbackReport(
cl::desc("Emit a diagnostic when \"fast\" instruction selection "
"falls back to SelectionDAG."));
-static cl::opt<bool>
-UseMBPI("use-mbpi",
- cl::desc("use Machine Branch Probability Info"),
- cl::init(true), cl::Hidden);
+static cl::opt<bool> UseMBPI("use-mbpi",
+ cl::desc("use Machine Branch Probability Info"),
+ cl::init(true), cl::Hidden);
#ifndef NDEBUG
-static cl::opt<std::string>
-FilterDAGBasicBlockName("filter-view-dags", cl::Hidden,
- cl::desc("Only display the basic block whose name "
- "matches this for all view-*-dags options"));
-static cl::opt<bool>
-ViewDAGCombine1("view-dag-combine1-dags", cl::Hidden,
- cl::desc("Pop up a window to show dags before the first "
- "dag combine pass"));
+static cl::opt<std::string> FilterDAGBasicBlockName(
+ "filter-view-dags", cl::Hidden,
+ cl::desc("Only display the basic block whose name "
+ "matches this for all view-*-dags options"));
static cl::opt<bool>
-ViewLegalizeTypesDAGs("view-legalize-types-dags", cl::Hidden,
- cl::desc("Pop up a window to show dags before legalize types"));
+ ViewDAGCombine1("view-dag-combine1-dags", cl::Hidden,
+ cl::desc("Pop up a window to show dags before the first "
+ "dag combine pass"));
+static cl::opt<bool> ViewLegalizeTypesDAGs(
+ "view-legalize-types-dags", cl::Hidden,
+ cl::desc("Pop up a window to show dags before legalize types"));
static cl::opt<bool>
ViewDAGCombineLT("view-dag-combine-lt-dags", cl::Hidden,
cl::desc("Pop up a window to show dags before the post "
@@ -164,18 +164,18 @@ static cl::opt<bool>
ViewLegalizeDAGs("view-legalize-dags", cl::Hidden,
cl::desc("Pop up a window to show dags before legalize"));
static cl::opt<bool>
-ViewDAGCombine2("view-dag-combine2-dags", cl::Hidden,
- cl::desc("Pop up a window to show dags before the second "
- "dag combine pass"));
-static cl::opt<bool>
-ViewISelDAGs("view-isel-dags", cl::Hidden,
- cl::desc("Pop up a window to show isel dags as they are selected"));
-static cl::opt<bool>
-ViewSchedDAGs("view-sched-dags", cl::Hidden,
- cl::desc("Pop up a window to show sched dags as they are processed"));
-static cl::opt<bool>
-ViewSUnitDAGs("view-sunit-dags", cl::Hidden,
- cl::desc("Pop up a window to show SUnit dags after they are processed"));
+ ViewDAGCombine2("view-dag-combine2-dags", cl::Hidden,
+ cl::desc("Pop up a window to show dags before the second "
+ "dag combine pass"));
+static cl::opt<bool> ViewISelDAGs(
+ "view-isel-dags", cl::Hidden,
+ cl::desc("Pop up a window to show isel dags as they are selected"));
+static cl::opt<bool> ViewSchedDAGs(
+ "view-sched-dags", cl::Hidden,
+ cl::desc("Pop up a window to show sched dags as they are processed"));
+static cl::opt<bool> ViewSUnitDAGs(
+ "view-sunit-dags", cl::Hidden,
+ cl::desc("Pop up a window to show SUnit dags after they are processed"));
#else
static const bool ViewDAGCombine1 = false, ViewLegalizeTypesDAGs = false,
ViewDAGCombineLT = false, ViewLegalizeDAGs = false,
@@ -193,7 +193,9 @@ static const bool ViewDAGCombine1 = false, ViewLegalizeTypesDAGs = false,
} \
} while (false)
#else
-#define ISEL_DUMP(X) do { } while (false)
+#define ISEL_DUMP(X) \
+ do { \
+ } while (false)
#endif
//===---------------------------------------------------------------------===//
@@ -211,14 +213,13 @@ MachinePassRegistry<RegisterScheduler::FunctionPassCtor>
//===---------------------------------------------------------------------===//
static cl::opt<RegisterScheduler::FunctionPassCtor, false,
RegisterPassParser<RegisterScheduler>>
-ISHeuristic("pre-RA-sched",
- cl::init(&createDefaultScheduler), cl::Hidden,
- cl::desc("Instruction schedulers available (before register"
- " allocation):"));
+ ISHeuristic("pre-RA-sched", cl::init(&createDefaultScheduler), cl::Hidden,
+ cl::desc("Instruction schedulers available (before register"
+ " allocation):"));
static RegisterScheduler
-defaultListDAGScheduler("default", "Best scheduler for the target",
- createDefaultScheduler);
+ defaultListDAGScheduler("default", "Best scheduler for the target",
+ createDefaultScheduler);
static bool dontUseFastISelFor(const Function &Fn) {
// Don't enable FastISel for functions with swiftasync Arguments.
@@ -232,83 +233,82 @@ static bool dontUseFastISelFor(const Function &Fn) {
namespace llvm {
- //===--------------------------------------------------------------------===//
- /// This class is used by SelectionDAGISel to temporarily override
- /// the optimization level on a per-function basis.
- class OptLevelChanger {
- SelectionDAGISel &IS;
- CodeGenOptLevel SavedOptLevel;
- bool SavedFastISel;
-
- public:
- OptLevelChanger(SelectionDAGISel &ISel, CodeGenOptLevel NewOptLevel)
- : IS(ISel) {
- SavedOptLevel = IS.OptLevel;
- SavedFastISel = IS.TM.Options.EnableFastISel;
- if (NewOptLevel != SavedOptLevel) {
- IS.OptLevel = NewOptLevel;
- IS.TM.setOptLevel(NewOptLevel);
- LLVM_DEBUG(dbgs() << "\nChanging optimization level for Function "
- << IS.MF->getFunction().getName() << "\n");
- LLVM_DEBUG(dbgs() << "\tBefore: -O" << static_cast<int>(SavedOptLevel)
- << " ; After: -O" << static_cast<int>(NewOptLevel)
- << "\n");
- if (NewOptLevel == CodeGenOptLevel::None)
- IS.TM.setFastISel(IS.TM.getO0WantsFastISel());
- }
- if (dontUseFastISelFor(IS.MF->getFunction()))
- IS.TM.setFastISel(false);
- LLVM_DEBUG(
- dbgs() << "\tFastISel is "
- << (IS.TM.Options.EnableFastISel ? "enabled" : "disabled")
- << "\n");
- }
+//===--------------------------------------------------------------------===//
+/// This class is used by SelectionDAGISel to temporarily override
+/// the optimization level on a per-function basis.
+class OptLevelChanger {
+ SelectionDAGISel &IS;
+ CodeGenOptLevel SavedOptLevel;
+ bool SavedFastISel;
- ~OptLevelChanger() {
- if (IS.OptLevel == SavedOptLevel)
- return;
- LLVM_DEBUG(dbgs() << "\nRestoring optimization level for Function "
+public:
+ OptLevelChanger(SelectionDAGISel &ISel, CodeGenOptLevel NewOptLevel)
+ : IS(ISel) {
+ SavedOptLevel = IS.OptLevel;
+ SavedFastISel = IS.TM.Options.EnableFastISel;
+ if (NewOptLevel != SavedOptLevel) {
+ IS.OptLevel = NewOptLevel;
+ IS.TM.setOptLevel(NewOptLevel);
+ LLVM_DEBUG(dbgs() << "\nChanging optimization level for Function "
<< IS.MF->getFunction().getName() << "\n");
- LLVM_DEBUG(dbgs() << "\tBefore: -O" << static_cast<int>(IS.OptLevel)
- << " ; After: -O" << static_cast<int>(SavedOptLevel) << "\n");
- IS.OptLevel = SavedOptLevel;
- IS.TM.setOptLevel(SavedOptLevel);
- IS.TM.setFastISel(SavedFastISel);
+ LLVM_DEBUG(dbgs() << "\tBefore: -O" << static_cast<int>(SavedOptLevel)
+ << " ; After: -O" << static_cast<int>(NewOptLevel)
+ << "\n");
+ if (NewOptLevel == CodeGenOptLevel::None)
+ IS.TM.setFastISel(IS.TM.getO0WantsFastISel());
}
- };
+ if (dontUseFastISelFor(IS.MF->getFunction()))
+ IS.TM.setFastISel(false);
+ LLVM_DEBUG(dbgs() << "\tFastISel is "
+ << (IS.TM.Options.EnableFastISel ? "enabled" : "disabled")
+ << "\n");
+ }
- //===--------------------------------------------------------------------===//
- /// createDefaultScheduler - This creates an instruction scheduler appropriate
- /// for the target.
- ScheduleDAGSDNodes *createDefaultScheduler(SelectionDAGISel *IS,
- CodeGenOptLevel OptLevel) {
- const TargetLowering *TLI = IS->TLI;
- const TargetSubtargetInfo &ST = IS->MF->getSubtarget();
-
- // Try first to see if the Target has its own way of selecting a scheduler
- if (auto *SchedulerCtor = ST.getDAGScheduler(OptLevel)) {
- return SchedulerCtor(IS, OptLevel);
- }
+ ~OptLevelChanger() {
+ if (IS.OptLevel == SavedOptLevel)
+ return;
+ LLVM_DEBUG(dbgs() << "\nRestoring optimization level for Function "
+ << IS.MF->getFunction().getName() << "\n");
+ LLVM_DEBUG(dbgs() << "\tBefore: -O" << static_cast<int>(IS.OptLevel)
+ << " ; After: -O" << static_cast<int>(SavedOptLevel)
+ << "\n");
+ IS.OptLevel = SavedOptLevel;
+ IS.TM.setOptLevel(SavedOptLevel);
+ IS.TM.setFastISel(SavedFastISel);
+ }
+};
- if (OptLevel == CodeGenOptLevel::None ||
- (ST.enableMachineScheduler() && ST.enableMachineSchedDefaultSched()) ||
- TLI->getSchedulingPreference() == Sched::Source)
- return createSourceListDAGScheduler(IS, OptLevel);
- if (TLI->getSchedulingPreference() == Sched::RegPressure)
- return createBURRListDAGScheduler(IS, OptLevel);
- if (TLI->getSchedulingPreference() == Sched::Hybrid)
- return createHybridListDAGScheduler(IS, OptLevel);
- if (TLI->getSchedulingPreference() == Sched::VLIW)
- return createVLIWDAGScheduler(IS, OptLevel);
- if (TLI->getSchedulingPreference() == Sched::Fast)
- return createFastDAGScheduler(IS, OptLevel);
- if (TLI->getSchedulingPreference() == Sched::Linearize)
- return createDAGLinearizer(IS, OptLevel);
- assert(TLI->getSchedulingPreference() == Sched::ILP &&
- "Unknown sched type!");
- return createILPListDAGScheduler(IS, OptLevel);
+//===--------------------------------------------------------------------===//
+/// createDefaultScheduler - This creates an instruction scheduler appropriate
+/// for the target.
+ScheduleDAGSDNodes *createDefaultScheduler(SelectionDAGISel *IS,
+ CodeGenOptLevel OptLevel) {
+ const TargetLowering *TLI = IS->TLI;
+ const TargetSubtargetInfo &ST = IS->MF->getSubtarget();
+
+ // Try first to see if the Target has its own way of selecting a scheduler
+ if (auto *SchedulerCtor = ST.getDAGScheduler(OptLevel)) {
+ return SchedulerCtor(IS, OptLevel);
}
+ if (OptLevel == CodeGenOptLevel::None ||
+ (ST.enableMachineScheduler() && ST.enableMachineSchedDefaultSched()) ||
+ TLI->getSchedulingPreference() == Sched::Source)
+ return createSourceListDAGScheduler(IS, OptLevel);
+ if (TLI->getSchedulingPreference() == Sched::RegPressure)
+ return createBURRListDAGScheduler(IS, OptLevel);
+ if (TLI->getSchedulingPreference() == Sched::Hybrid)
+ return createHybridListDAGScheduler(IS, OptLevel);
+ if (TLI->getSchedulingPreference() == Sched::VLIW)
+ return createVLIWDAGScheduler(IS, OptLevel);
+ if (TLI->getSchedulingPreference() == Sched::Fast)
+ return createFastDAGScheduler(IS, OptLevel);
+ if (TLI->getSchedulingPreference() == Sched::Linearize)
+ return createDAGLinearizer(IS, OptLevel);
+ assert(TLI->getSchedulingPreference() == Sched::ILP && "Unknown sched type!");
+ return createILPListDAGScheduler(IS, OptLevel);
+}
+
} // end namespace llvm
MachineBasicBlock *
@@ -316,8 +316,8 @@ TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
MachineBasicBlock *MBB) const {
#ifndef NDEBUG
dbgs() << "If a target marks an instruction with "
- "'usesCustomInserter', it must implement "
- "TargetLowering::EmitInstrWithCustomInserter!\n";
+ "'usesCustomInserter', it must implement "
+ "TargetLowering::EmitInstrWithCustomInserter!\n";
#endif
llvm_unreachable(nullptr);
}
@@ -396,7 +396,7 @@ SelectionDAGISel::~SelectionDAGISel() {
void SelectionDAGISelLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
CodeGenOptLevel OptLevel = Selector->OptLevel;
if (OptLevel != CodeGenOptLevel::None)
- AU.addRequired<AAResultsWrapperPass>();
+ AU.addRequired<AAResultsWrapperPass>();
AU.addRequired<GCModuleInfo>();
AU.addRequired<StackProtector>();
AU.addPreserved<GCModuleInfo>();
@@ -406,14 +406,14 @@ void SelectionDAGISelLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
#endif
AU.addRequired<AssumptionCacheTracker>();
if (UseMBPI && OptLevel != CodeGenOptLevel::None)
- AU.addRequired<BranchProbabilityInfoWrapperPass>();
+ AU.addRequired<BranchProbabilityInfoWrapperPass>();
AU.addRequired<ProfileSummaryInfoWrapperPass>();
// AssignmentTrackingAnalysis only runs if assignment tracking is enabled for
// the module.
AU.addRequired<AssignmentTrackingAnalysis>();
AU.addPreserved<AssignmentTrackingAnalysis>();
if (OptLevel != CodeGenOptLevel::None)
- LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
+ LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
MachineFunctionPass::getAnalysisUsage(AU);
}
@@ -658,7 +658,7 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
// Insert copies in the entry block and the return blocks.
if (FuncInfo->SplitCSR) {
- SmallVector<MachineBasicBlock*, 4> Returns;
+ SmallVector<MachineBasicBlock *, 4> Returns;
// Collect all the return blocks.
for (MachineBasicBlock &MBB : mf) {
if (!MBB.succ_empty())
@@ -857,7 +857,8 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock::const_iterator Begin,
// Lower the instructions. If a call is emitted as a tail call, cease emitting
// nodes for this block. If an instruction is elided, don't emit it, but do
// handle any debug-info attached to it.
- for (BasicBlock::const_iterator I = Begin; I != End && !SDB->HasTailCall; ++I) {
+ for (BasicBlock::const_iterator I = Begin; I != End && !SDB->HasTailCall;
+ ++I) {
if (!ElidedArgCopyInstrs.count(&*I))
SDB->visit(*I);
else
@@ -876,7 +877,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock::const_iterator Begin,
void SelectionDAGISel::ComputeLiveOutVRegInfo() {
SmallPtrSet<SDNode *, 16> Added;
- SmallVector<SDNode*, 128> Worklist;
+ SmallVector<SDNode *, 128> Worklist;
Worklist.push_back(CurDAG->getRoot().getNode());
Added.insert(CurDAG->getRoot().getNode());
@@ -922,9 +923,9 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
CurDAG->NewNodesMustHaveLegalTypes = false;
#ifndef NDEBUG
- MatchFilterBB = (FilterDAGBasicBlockName.empty() ||
- FilterDAGBasicBlockName ==
- FuncInfo->MBB->getBasicBlock()->getName());
+ MatchFilterBB =
+ (FilterDAGBasicBlockName.empty() ||
+ FilterDAGBasicBlockName == FuncInfo->MBB->getBasicBlock()->getName());
#endif
#ifdef NDEBUG
if (ViewDAGCombine1 || ViewLegalizeTypesDAGs || ViewDAGCombineLT ||
@@ -1175,7 +1176,7 @@ class ISelUpdater : public SelectionDAG::DAGUpdateListener {
public:
ISelUpdater(SelectionDAG &DAG, SelectionDAG::allnodes_iterator &isp)
- : SelectionDAG::DAGUpdateListener(DAG), ISelPosition(isp) {}
+ : SelectionDAG::DAGUpdateListener(DAG), ISelPosition(isp) {}
/// NodeDeleted - Handle nodes deleted from the graph. If the node being
/// deleted is the current ISelPosition node, update ISelPosition.
@@ -1267,7 +1268,7 @@ void SelectionDAGISel::DoInstructionSelection() {
// a reference to the root node, preventing it from being deleted,
// and tracking any changes of the root.
HandleSDNode Dummy(CurDAG->getRoot());
- SelectionDAG::allnodes_iterator ISelPosition (CurDAG->getRoot().getNode());
+ SelectionDAG::allnodes_iterator ISelPosition(CurDAG->getRoot().getNode());
++ISelPosition;
// Make sure that ISelPosition gets properly updated when nodes are deleted
@@ -1339,8 +1340,8 @@ void SelectionDAGISel::DoInstructionSelection() {
ActionVT = Node->getValueType(0);
break;
}
- if (TLI->getOperationAction(Node->getOpcode(), ActionVT)
- == TargetLowering::Expand)
+ if (TLI->getOperationAction(Node->getOpcode(), ActionVT) ==
+ TargetLowering::Expand)
Node = CurDAG->mutateStrictFPToFP(Node);
}
@@ -1439,8 +1440,7 @@ bool SelectionDAGISel::PrepareEHLandingPad() {
MCSymbol *Label = MF->addLandingPad(MBB);
const MCInstrDesc &II = TII->get(TargetOpcode::EH_LABEL);
- BuildMI(*MBB, FuncInfo->InsertPt, SDB->getCurDebugLoc(), II)
- .addSym(Label);
+ BuildMI(*MBB, FuncInfo->InsertPt, SDB->getCurDebugLoc(), II).addSym(Label);
// If the unwinder does not preserve all registers, ensure that the
// function marks the clobbered registers as used.
@@ -1476,6 +1476,11 @@ void SelectionDAGISel::reportIPToStateForBlocks(MachineFunction *MF) {
if (BB->getFirstMayFaultInst()) {
// Report IP range only for blocks with Faulty inst
auto MBBb = MBB.getFirstNonPHI();
+
+ // Avoids attempting to dereference a sentintel which fails an assert
+ if (MBBb == MBB.instr_end())
+ continue;
+
MachineInstr *MIb = &*MBBb;
if (MIb->isTerminator())
continue;
@@ -1627,7 +1632,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
FastIS = TLI->createFastISel(*FuncInfo, LibInfo);
}
- ReversePostOrderTraversal<const Function*> RPOT(&Fn);
+ ReversePostOrderTraversal<const Function *> RPOT(&Fn);
// Lower arguments up front. An RPO iteration always visits the entry block
// first.
@@ -1651,8 +1656,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
++NumFastIselFailLowerArguments;
OptimizationRemarkMissed R("sdagisel", "FastISelFailure",
- Fn.getSubprogram(),
- &Fn.getEntryBlock());
+ Fn.getSubprogram(), &Fn.getEntryBlock());
R << "FastISel didn't lower all arguments: "
<< ore::NV("Prototype", Fn.getFunctionType());
reportFastISelFailure(*MF, *ORE, R, EnableFastISelAbort > 1);
@@ -1919,8 +1923,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
SDB->SPDescriptor.resetPerFunctionState();
}
-void
-SelectionDAGISel::FinishBasicBlock() {
+void SelectionDAGISel::FinishBasicBlock() {
LLVM_DEBUG(dbgs() << "Total amount of phi nodes to update: "
<< FuncInfo->PHINodesToUpdate.size() << "\n";
for (unsigned i = 0, e = FuncInfo->PHINodesToUpdate.size(); i != e;
@@ -1947,8 +1950,7 @@ SelectionDAGISel::FinishBasicBlock() {
// Add load and check to the basicblock.
FuncInfo->MBB = ParentMBB;
- FuncInfo->InsertPt =
- findSplitPointForStackProtector(ParentMBB, *TII);
+ FuncInfo->InsertPt = findSplitPointForStackProtector(ParentMBB, *TII);
SDB->visitSPDescriptorParent(SDB->SPDescriptor, ParentMBB);
CurDAG->setRoot(SDB-...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/107031
More information about the llvm-commits
mailing list