ScalarEvolution: Do not keep temporary PHI values in ValueExprMap
authorTobias Grosser <tobias@grosser.es>
Sun, 21 Feb 2016 17:42:10 +0000 (17:42 +0000)
committerTobias Grosser <tobias@grosser.es>
Sun, 21 Feb 2016 17:42:10 +0000 (17:42 +0000)
Before this patch simplified SCEV expressions for PHI nodes were only returned
the very first time getSCEV() was called, but later calls to getSCEV always
returned the non-simplified value, which had "temporarily" been stored in the
ValueExprMap, but was never removed and consequently blocked the caching of the
simplified PHI expression.

llvm-svn: 261485

llvm/lib/Analysis/ScalarEvolution.cpp
llvm/unittests/Analysis/ScalarEvolutionTest.cpp

index 4c3c5c7..6e8fa5d 100644 (file)
@@ -3897,6 +3897,11 @@ const SCEV *ScalarEvolution::createAddRecFromPHI(PHINode *PN) {
     }
   }
 
+  // Remove the temporary PHI node SCEV that has been inserted while intending
+  // to create an AddRecExpr for this PHI node. We can not keep this temporary
+  // as it will prevent later (possibly simpler) SCEV expressions to be added
+  // to the ValueExprMap.
+  ValueExprMap.erase(PN);
   return nullptr;
 }
 
index 938dafe..4089e5d 100644 (file)
@@ -237,5 +237,31 @@ TEST_F(ScalarEvolutionsTest, SCEVMultiplyAddRecs) {
   EXPECT_EQ(Product->getOperand(8), SE.getAddExpr(Sum));
 }
 
+TEST_F(ScalarEvolutionsTest, SimplifiedPHI) {
+  FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context),
+                                              std::vector<Type *>(), false);
+  Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+  BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", F);
+  BasicBlock *LoopBB = BasicBlock::Create(Context, "loop", F);
+  BasicBlock *ExitBB = BasicBlock::Create(Context, "exit", F);
+  BranchInst::Create(LoopBB, EntryBB);
+  BranchInst::Create(LoopBB, ExitBB, UndefValue::get(Type::getInt1Ty(Context)),
+                     LoopBB);
+  ReturnInst::Create(Context, nullptr, ExitBB);
+  auto *Ty = Type::getInt32Ty(Context);
+  auto *PN = PHINode::Create(Ty, 2, "", &*LoopBB->begin());
+  PN->addIncoming(Constant::getNullValue(Ty), EntryBB);
+  PN->addIncoming(UndefValue::get(Ty), LoopBB);
+  ScalarEvolution SE = buildSE(*F);
+  auto *S1 = SE.getSCEV(PN);
+  auto *S2 = SE.getSCEV(PN);
+  assert(isa<SCEVConstant>(S1) && "Expected a SCEV Constant");
+
+  // At some point, only the first call to getSCEV returned the simplified
+  // SCEVConstant and later calls just returned a SCEVUnknown referencing the
+  // PHI node.
+  assert(S1 == S2 && "Expected identical SCEV values");
+}
+
 }  // end anonymous namespace
 }  // end namespace llvm