]> granicus.if.org Git - llvm/commitdiff
SimplifyInstruction does not imply DCE
authorDavid Majnemer <david.majnemer@gmail.com>
Fri, 24 Jun 2016 19:34:46 +0000 (19:34 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Fri, 24 Jun 2016 19:34:46 +0000 (19:34 +0000)
We cannot remove an instruction with no uses just because
SimplifyInstruction succeeds.  It may have side effects.

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

lib/Transforms/Scalar/EarlyCSE.cpp
lib/Transforms/Scalar/GVN.cpp
lib/Transforms/Scalar/JumpThreading.cpp
lib/Transforms/Scalar/LoopRotation.cpp
lib/Transforms/Utils/CloneFunction.cpp
lib/Transforms/Utils/Local.cpp
lib/Transforms/Utils/LoopUnroll.cpp
lib/Transforms/Utils/SimplifyCFG.cpp
test/Transforms/GVN/volatile.ll

index 0e93b0a37b099af62531ec7a200df13f90c383b3..9d0ef42e0396d7a42405ec7f8f14a6c720bfef23 100644 (file)
@@ -582,11 +582,18 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
     // its simpler value.
     if (Value *V = SimplifyInstruction(Inst, DL, &TLI, &DT, &AC)) {
       DEBUG(dbgs() << "EarlyCSE Simplify: " << *Inst << "  to: " << *V << '\n');
-      Inst->replaceAllUsesWith(V);
-      Inst->eraseFromParent();
-      Changed = true;
-      ++NumSimplify;
-      continue;
+      if (!Inst->use_empty()) {
+        Inst->replaceAllUsesWith(V);
+        Changed = true;
+      }
+      if (isInstructionTriviallyDead(Inst, &TLI)) {
+        Inst->eraseFromParent();
+        Changed = true;
+      }
+      if (Changed) {
+        ++NumSimplify;
+        continue;
+      }
     }
 
     // If this is a simple instruction that we can value number, process it.
index 944e06d4391703dc73a11b8ef98efdfdd2ace818..a963b2f50edae3c4e763aa277453f7774455861e 100644 (file)
@@ -2056,12 +2056,21 @@ bool GVN::processInstruction(Instruction *I) {
   // "%z = and i32 %x, %y" becomes "%z = and i32 %x, %x" which we now simplify.
   const DataLayout &DL = I->getModule()->getDataLayout();
   if (Value *V = SimplifyInstruction(I, DL, TLI, DT, AC)) {
-    I->replaceAllUsesWith(V);
-    if (MD && V->getType()->getScalarType()->isPointerTy())
-      MD->invalidateCachedPointerInfo(V);
-    markInstructionForDeletion(I);
-    ++NumGVNSimpl;
-    return true;
+    bool Changed = false;
+    if (!I->use_empty()) {
+      I->replaceAllUsesWith(V);
+      Changed = true;
+    }
+    if (isInstructionTriviallyDead(I, TLI)) {
+      markInstructionForDeletion(I);
+      Changed = true;
+    }
+    if (Changed) {
+      if (MD && V->getType()->getScalarType()->isPointerTy())
+        MD->invalidateCachedPointerInfo(V);
+      ++NumGVNSimpl;
+      return true;
+    }
   }
 
   if (IntrinsicInst *IntrinsicI = dyn_cast<IntrinsicInst>(I))
index 1d8d2a5e469b502e46e399b1b3d9250ddf39d998..e7957f9599a88725a0183c3e5a93a974cad574ba 100644 (file)
@@ -1746,13 +1746,18 @@ bool JumpThreadingPass::DuplicateCondBranchOnPHIIntoPred(
     // phi translation.
     if (Value *IV =
             SimplifyInstruction(New, BB->getModule()->getDataLayout())) {
-      delete New;
       ValueMapping[&*BI] = IV;
+      if (!New->mayHaveSideEffects()) {
+        delete New;
+        New = nullptr;
+      }
     } else {
+      ValueMapping[&*BI] = New;
+    }
+    if (New) {
       // Otherwise, insert the new instruction into the block.
       New->setName(BI->getName());
       PredBB->getInstList().insert(OldPredBranch->getIterator(), New);
-      ValueMapping[&*BI] = New;
     }
   }
 
index c6709d5334a0f1a1b51f0e124401057cbf40debe..46db8f1210b6957d12090926ab944c3558144b8b 100644 (file)
@@ -312,13 +312,18 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
     if (V && LI->replacementPreservesLCSSAForm(C, V)) {
       // If so, then delete the temporary instruction and stick the folded value
       // in the map.
-      delete C;
       ValueMap[Inst] = V;
+      if (!C->mayHaveSideEffects()) {
+        delete C;
+        C = nullptr;
+      }
     } else {
+      ValueMap[Inst] = C;
+    }
+    if (C) {
       // Otherwise, stick the new instruction into the new block!
       C->setName(Inst->getName());
       C->insertBefore(LoopEntryBranch);
-      ValueMap[Inst] = C;
     }
   }
 
index 6ff05fe3e5900f19385ec8f1b0c0e47db935611b..59b109ead631397405935a2bfeb34fb143122476 100644 (file)
@@ -279,6 +279,7 @@ void PruningFunctionCloner::CloneBlock(const BasicBlock *BB,
        II != IE; ++II) {
 
     Instruction *NewInst = II->clone();
+    VMap[&*II] = NewInst; // Add instruction map to value.
 
     // Eagerly remap operands to the newly cloned instruction, except for PHI
     // nodes for which we defer processing until we update the CFG.
@@ -297,14 +298,15 @@ void PruningFunctionCloner::CloneBlock(const BasicBlock *BB,
           V = MappedV;
 
         VMap[&*II] = V;
-        delete NewInst;
-        continue;
+        if (!NewInst->mayHaveSideEffects()) {
+          delete NewInst;
+          continue;
+        }
       }
     }
 
     if (II->hasName())
       NewInst->setName(II->getName()+NameSuffix);
-    VMap[&*II] = NewInst; // Add instruction map to value.
     NewBB->getInstList().push_back(NewInst);
     hasCalls |= (isa<CallInst>(II) && !isa<DbgInfoIntrinsic>(II));
 
index 4f8935dd971825a7b98d11f7d8215138707cb17a..4d76aae29713084dab3822723d76796f53126670 100644 (file)
@@ -456,14 +456,23 @@ simplifyAndDCEInstruction(Instruction *I,
   if (Value *SimpleV = SimplifyInstruction(I, DL)) {
     // Add the users to the worklist. CAREFUL: an instruction can use itself,
     // in the case of a phi node.
-    for (User *U : I->users())
-      if (U != I)
+    for (User *U : I->users()) {
+      if (U != I) {
         WorkList.insert(cast<Instruction>(U));
+      }
+    }
 
     // Replace the instruction with its simplified value.
-    I->replaceAllUsesWith(SimpleV);
-    I->eraseFromParent();
-    return true;
+    bool Changed = false;
+    if (!I->use_empty()) {
+      I->replaceAllUsesWith(SimpleV);
+      Changed = true;
+    }
+    if (isInstructionTriviallyDead(I, TLI)) {
+      I->eraseFromParent();
+      Changed = true;
+    }
+    return Changed;
   }
   return false;
 }
index f7e5c0c49f8fde2aaf7f50bc6868a46ea13945f3..9e53b1c2647ba8adc1f6c79abeccd7734c04ecb7 100644 (file)
@@ -623,18 +623,17 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
   // go.
   const DataLayout &DL = Header->getModule()->getDataLayout();
   const std::vector<BasicBlock*> &NewLoopBlocks = L->getBlocks();
-  for (BasicBlock *BB : NewLoopBlocks)
+  for (BasicBlock *BB : NewLoopBlocks) {
     for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
       Instruction *Inst = &*I++;
 
+      if (Value *V = SimplifyInstruction(Inst, DL))
+        if (LI->replacementPreservesLCSSAForm(Inst, V))
+          Inst->replaceAllUsesWith(V);
       if (isInstructionTriviallyDead(Inst))
         BB->getInstList().erase(Inst);
-      else if (Value *V = SimplifyInstruction(Inst, DL))
-        if (LI->replacementPreservesLCSSAForm(Inst, V)) {
-          Inst->replaceAllUsesWith(V);
-          BB->getInstList().erase(Inst);
-        }
     }
+  }
 
   NumCompletelyUnrolled += CompletelyUnroll;
   ++NumUnrolled;
index 6e1ac2c9a691cc9b292ecb5ada569b4e7c6aa572..d22f5c63dee1b0661e3948378ad3de527ac108b4 100644 (file)
@@ -1885,14 +1885,19 @@ static bool FoldCondBranchOnPHI(BranchInst *BI, const DataLayout &DL) {
 
       // Check for trivial simplification.
       if (Value *V = SimplifyInstruction(N, DL)) {
-        TranslateMap[&*BBI] = V;
-        delete N; // Instruction folded away, don't need actual inst
+        if (!BBI->use_empty())
+          TranslateMap[&*BBI] = V;
+        if (!N->mayHaveSideEffects()) {
+          delete N; // Instruction folded away, don't need actual inst
+          N = nullptr;
+        }
       } else {
-        // Insert the new instruction into its new home.
-        EdgeBB->getInstList().insert(InsertPt, N);
         if (!BBI->use_empty())
           TranslateMap[&*BBI] = N;
       }
+      // Insert the new instruction into its new home.
+      if (N)
+        EdgeBB->getInstList().insert(InsertPt, N);
     }
 
     // Loop over all of the edges from PredBB to BB, changing them to branch
index b31058db4ea8ed2824d9844e0632e0e39bc2915c..ccc5bbfa48e48fe7babeed255febff0b988f48aa 100644 (file)
@@ -152,6 +152,16 @@ exit:
   ret i32 %add
 }
 
+define i32 @test9(i32* %V) {
+entry:
+  %load = load volatile i32, i32* %V, !range !0
+  ret i32 %load
+}
+; CHECK-LABEL: test9
+; CHECK: load volatile
+; CHECK: ret i32 0
+
 declare void @use(i32) readonly
 declare void @clobber(i32* %p, i32* %q)
 
+!0 = !{ i32 0, i32 1 }