[globalisel][combine] When placing truncates, handle the case when the BB is empty

GlobalISel uses MIR with implicit fallthrough on each basic block. As a result,
getFirstNonPhi() can return end().

llvm-svn: 343829
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index fe68c04..557bc88 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -110,7 +110,8 @@
 /// want to try harder to find a dominating block.
 static void InsertInsnsWithoutSideEffectsBeforeUse(
     MachineIRBuilder &Builder, MachineInstr &DefMI, MachineOperand &UseMO,
-    std::function<void(MachineBasicBlock::iterator)> Inserter) {
+    std::function<void(MachineBasicBlock *, MachineBasicBlock::iterator)>
+        Inserter) {
   MachineInstr &UseMI = *UseMO.getParent();
 
   MachineBasicBlock *InsertBB = UseMI.getParent();
@@ -125,16 +126,26 @@
   // the def instead of at the start of the block.
   if (InsertBB == DefMI.getParent()) {
     MachineBasicBlock::iterator InsertPt = &DefMI;
-    Inserter(std::next(InsertPt));
+    Inserter(InsertBB, std::next(InsertPt));
     return;
   }
 
   // Otherwise we want the start of the BB
-  Inserter(InsertBB->getFirstNonPHI());
+  Inserter(InsertBB, InsertBB->getFirstNonPHI());
 }
 } // end anonymous namespace
 
 bool CombinerHelper::tryCombineExtendingLoads(MachineInstr &MI) {
+  struct InsertionPoint {
+    MachineOperand *UseMO;
+    MachineBasicBlock *InsertIntoBB;
+    MachineBasicBlock::iterator InsertBefore;
+    InsertionPoint(MachineOperand *UseMO, MachineBasicBlock *InsertIntoBB,
+                   MachineBasicBlock::iterator InsertBefore)
+        : UseMO(UseMO), InsertIntoBB(InsertIntoBB), InsertBefore(InsertBefore) {
+    }
+  };
+
   // We match the loads and follow the uses to the extend instead of matching
   // the extends and following the def to the load. This is because the load
   // must remain in the same position for correctness (unless we also add code
@@ -193,7 +204,7 @@
 
   // Rewrite all the uses to fix up the types.
   SmallVector<MachineInstr *, 1> ScheduleForErase;
-  SmallVector<std::pair<MachineOperand *, MachineInstr *>, 4> ScheduleForInsert;
+  SmallVector<InsertionPoint, 4> ScheduleForInsert;
   for (auto &UseMO : MRI.use_operands(LoadValue.getReg())) {
     MachineInstr *UseMI = UseMO.getParent();
 
@@ -243,8 +254,9 @@
           //    ... = ... %3(s64)
           InsertInsnsWithoutSideEffectsBeforeUse(
               Builder, MI, UseMO,
-              [&](MachineBasicBlock::iterator InsertBefore) {
-                ScheduleForInsert.emplace_back(&UseMO, &*InsertBefore);
+              [&](MachineBasicBlock *InsertIntoBB,
+                  MachineBasicBlock::iterator InsertBefore) {
+                ScheduleForInsert.emplace_back(&UseMO, InsertIntoBB, InsertBefore);
               });
         }
         continue;
@@ -259,27 +271,29 @@
     // The use isn't an extend. Truncate back to the type we originally loaded.
     // This is free on many targets.
     InsertInsnsWithoutSideEffectsBeforeUse(
-        Builder, MI, UseMO, [&](MachineBasicBlock::iterator InsertBefore) {
-          ScheduleForInsert.emplace_back(&UseMO, &*InsertBefore);
+        Builder, MI, UseMO,
+        [&](MachineBasicBlock *InsertIntoBB,
+            MachineBasicBlock::iterator InsertBefore) {
+          ScheduleForInsert.emplace_back(&UseMO, InsertIntoBB, InsertBefore);
         });
   }
 
   DenseMap<MachineBasicBlock *, MachineInstr *> EmittedInsns;
   for (auto &InsertionInfo : ScheduleForInsert) {
-    MachineOperand *UseMO = InsertionInfo.first;
-    MachineInstr *InsertBefore = InsertionInfo.second;
+    MachineOperand *UseMO = InsertionInfo.UseMO;
+    MachineBasicBlock *InsertIntoBB = InsertionInfo.InsertIntoBB;
+    MachineBasicBlock::iterator InsertBefore = InsertionInfo.InsertBefore;
 
-    MachineInstr *PreviouslyEmitted =
-        EmittedInsns.lookup(InsertBefore->getParent());
+    MachineInstr *PreviouslyEmitted = EmittedInsns.lookup(InsertIntoBB);
     if (PreviouslyEmitted) {
       UseMO->setReg(PreviouslyEmitted->getOperand(0).getReg());
       continue;
     }
 
-    Builder.setInsertPt(*InsertBefore->getParent(), InsertBefore);
+    Builder.setInsertPt(*InsertIntoBB, InsertBefore);
     unsigned NewDstReg = MRI.cloneVirtualRegister(MI.getOperand(0).getReg());
     MachineInstr *NewMI = Builder.buildTrunc(NewDstReg, ChosenDstReg);
-    EmittedInsns[InsertBefore->getParent()] = NewMI;
+    EmittedInsns[InsertIntoBB] = NewMI;
     UseMO->setReg(NewDstReg);
     Observer.createdInstr(*NewMI);
   }