Fix a bug in sdisel switch lowering code. When it updates the phi nodes in switch...
authorEvan Cheng <evan.cheng@apple.com>
Fri, 18 Sep 2009 08:16:04 +0000 (08:16 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Fri, 18 Sep 2009 08:16:04 +0000 (08:16 +0000)
This can be seen on CodeGen/Generic/2006-09-06-SwitchLowering.ll. But it's not known to cause any real regression (but I have added an assertion for it now).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82214 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/MachineBasicBlock.h
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

index 2a9e86a04c09f7648925c251fb7931f27437a592..2bfb1babbb1d27fd6796f19698eb11854a42c62b 100644 (file)
@@ -149,6 +149,10 @@ public:
     return (unsigned)Predecessors.size();
   }
   bool                 pred_empty() const { return Predecessors.empty(); }
+  bool                 isPred(MachineBasicBlock *MBB) const {
+    return std::find(pred_begin(), pred_end(), MBB) != pred_end();
+  }
+
   succ_iterator        succ_begin()       { return Successors.begin();   }
   const_succ_iterator  succ_begin() const { return Successors.begin();   }
   succ_iterator        succ_end()         { return Successors.end();     }
@@ -165,6 +169,9 @@ public:
     return (unsigned)Successors.size();
   }
   bool                 succ_empty() const { return Successors.empty();   }
+  bool                 isSucc(MachineBasicBlock *MBB) const {
+    return std::find(succ_begin(), succ_end(), MBB) != succ_end();
+  }
 
   // LiveIn management methods.
 
index 19ea647311519d464d4a99407209a16d2fa35475..e2fab1b1b80046624c91da0e013426310a939f0f 100644 (file)
@@ -982,6 +982,7 @@ SelectionDAGISel::FinishBasicBlock() {
   
   // If we generated any switch lowering information, build and codegen any
   // additional DAGs necessary.
+  SmallSet<unsigned, 4> Processed;
   for (unsigned i = 0, e = SDL->SwitchCases.size(); i != e; ++i) {
     // Set the current basic block to the mbb we wish to insert the code into
     BB = SDL->SwitchCases[i].ThisBB;
@@ -1004,12 +1005,18 @@ SelectionDAGISel::FinishBasicBlock() {
         for (unsigned pn = 0; ; ++pn) {
           assert(pn != SDL->PHINodesToUpdate.size() &&
                  "Didn't find PHI entry!");
-          if (SDL->PHINodesToUpdate[pn].first == Phi) {
-            Phi->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[pn].
-                                                      second, false));
-            Phi->addOperand(MachineOperand::CreateMBB(SDL->SwitchCases[i].ThisBB));
+          if (SDL->PHINodesToUpdate[pn].first != Phi)
+            continue;
+          if (!Processed.insert(pn))
+            // Already processed, done. We can't have the value from more than
+            // one edges.
             break;
-          }
+          Phi->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[pn].
+                                                    second, false));
+          assert(BB->isPred(SDL->SwitchCases[i].ThisBB) &&
+                 "phi value cannot come from a bb that is not a predecessor!");
+          Phi->addOperand(MachineOperand::CreateMBB(SDL->SwitchCases[i].ThisBB));
+          break;
         }
       }