[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