Avoid deleting individual instructions until AFTER dead blocks have dropped
[oota-llvm.git] / lib / Transforms / Scalar / InstructionCombining.cpp
index 0f676426e1ba3cecdbbdb8579d6a978c1a26fc42..6032ab956eb674247e05c6f1031ddcfe62893e17 100644 (file)
@@ -26,6 +26,7 @@
 #include "llvm/Support/InstIterator.h"
 #include "llvm/Support/InstVisitor.h"
 #include "Support/StatisticReporter.h"
+#include <algorithm>
 
 static Statistic<> NumCombined("instcombine\t- Number of insts combined");
 
@@ -123,8 +124,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator *I) {
   Value *LHS = I->getOperand(0), *RHS = I->getOperand(1);
 
   // Eliminate 'add int %X, 0'
-  if (I->getType()->isIntegral() &&
-      RHS == Constant::getNullValue(I->getType())) {
+  if (RHS == Constant::getNullValue(I->getType())) {
     AddUsesToWorkList(I);         // Add all modified instrs to worklist
     I->replaceAllUsesWith(LHS);
     return I;
@@ -186,7 +186,7 @@ Instruction *InstCombiner::visitSub(BinaryOperator *I) {
   // not used by anyone else...
   //
   if (BinaryOperator *Op1I = dyn_cast<BinaryOperator>(Op1))
-    if (Op1I->use_size() == 1) {
+    if (Op1I->use_size() == 1 && Op1I->getOpcode() == Instruction::Sub) {
       // Swap the two operands of the subexpr...
       Value *IIOp0 = Op1I->getOperand(0), *IIOp1 = Op1I->getOperand(1);
       Op1I->setOperand(0, IIOp1);
@@ -551,8 +551,18 @@ bool InstCombiner::runOnFunction(Function *F) {
     if (Result) {
       ++NumCombined;
       // Should we replace the old instruction with a new one?
-      if (Result != I)
+      if (Result != I) {
+        // Instructions can end up on the worklist more than once.  Make sure
+        // we do not process an instruction that has been deleted.
+        std::vector<Instruction*>::iterator It = std::find(WorkList.begin(),
+                                                           WorkList.end(), I);
+        while (It != WorkList.end()) {
+          It = WorkList.erase(It);
+          It = std::find(It, WorkList.end(), I);
+        }
+
         ReplaceInstWithInst(I, Result);
+      }
 
       WorkList.push_back(Result);
       AddUsesToWorkList(Result);