summaryrefslogtreecommitdiffstats
path: root/llvm/unittests/Analysis/MemorySSATest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/unittests/Analysis/MemorySSATest.cpp')
-rw-r--r--llvm/unittests/Analysis/MemorySSATest.cpp192
1 files changed, 192 insertions, 0 deletions
diff --git a/llvm/unittests/Analysis/MemorySSATest.cpp b/llvm/unittests/Analysis/MemorySSATest.cpp
index 76a49196ac3..06d301ea9bf 100644
--- a/llvm/unittests/Analysis/MemorySSATest.cpp
+++ b/llvm/unittests/Analysis/MemorySSATest.cpp
@@ -1393,3 +1393,195 @@ TEST_F(MemorySSATest, TestOptimizedDefsAreProperUses) {
(std::vector<const MemoryDef *>{StoreAAccess, StoreAAccess,
StoreBAccess}));
}
+
+// entry
+// |
+// header
+// / \
+// body |
+// \ /
+// exit
+// header:
+// ; 1 = MemoryDef(liveOnEntry)
+// body:
+// ; 2 = MemoryDef(1)
+// exit:
+// ; 3 = MemoryPhi({body, 2}, {header, 1})
+// ; 4 = MemoryDef(3); optimized to 3, cannot optimize thorugh phi.
+// Insert edge: entry -> exit, check mssa Update is correct.
+TEST_F(MemorySSATest, TestAddedEdgeToBlockWithPhiNotOpt) {
+ F = Function::Create(
+ FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
+ GlobalValue::ExternalLinkage, "F", &M);
+ Argument *PointerArg = &*F->arg_begin();
+ BasicBlock *Entry(BasicBlock::Create(C, "entry", F));
+ BasicBlock *Header(BasicBlock::Create(C, "header", F));
+ BasicBlock *Body(BasicBlock::Create(C, "body", F));
+ BasicBlock *Exit(BasicBlock::Create(C, "exit", F));
+ B.SetInsertPoint(Entry);
+ BranchInst::Create(Header, Entry);
+ B.SetInsertPoint(Header);
+ B.CreateStore(B.getInt8(16), PointerArg);
+ B.CreateCondBr(B.getTrue(), Exit, Body);
+ B.SetInsertPoint(Body);
+ B.CreateStore(B.getInt8(16), PointerArg);
+ BranchInst::Create(Exit, Body);
+ B.SetInsertPoint(Exit);
+ StoreInst *S1 = B.CreateStore(B.getInt8(16), PointerArg);
+
+ setupAnalyses();
+ MemorySSA &MSSA = *Analyses->MSSA;
+ MemorySSAWalker *Walker = Analyses->Walker;
+ std::unique_ptr<MemorySSAUpdater> MSSAU =
+ make_unique<MemorySSAUpdater>(&MSSA);
+
+ MemoryPhi *Phi = MSSA.getMemoryAccess(Exit);
+ EXPECT_EQ(Phi, Walker->getClobberingMemoryAccess(S1));
+
+ // Alter CFG, add edge: entry -> exit
+ Entry->getTerminator()->eraseFromParent();
+ B.SetInsertPoint(Entry);
+ B.CreateCondBr(B.getTrue(), Header, Exit);
+ SmallVector<CFGUpdate, 1> Updates;
+ Updates.push_back({cfg::UpdateKind::Insert, Entry, Exit});
+ Analyses->DT.applyUpdates(Updates);
+ MSSAU->applyInsertUpdates(Updates, Analyses->DT);
+ EXPECT_EQ(Phi, Walker->getClobberingMemoryAccess(S1));
+}
+
+// entry
+// |
+// header
+// / \
+// body |
+// \ /
+// exit
+// header:
+// ; 1 = MemoryDef(liveOnEntry)
+// body:
+// ; 2 = MemoryDef(1)
+// exit:
+// ; 3 = MemoryPhi({body, 2}, {header, 1})
+// ; 4 = MemoryDef(3); optimize this to 1 now, added edge should invalidate
+// the optimized access.
+// Insert edge: entry -> exit, check mssa Update is correct.
+TEST_F(MemorySSATest, TestAddedEdgeToBlockWithPhiOpt) {
+ F = Function::Create(
+ FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
+ GlobalValue::ExternalLinkage, "F", &M);
+ Argument *PointerArg = &*F->arg_begin();
+ Type *Int8 = Type::getInt8Ty(C);
+ BasicBlock *Entry(BasicBlock::Create(C, "entry", F));
+ BasicBlock *Header(BasicBlock::Create(C, "header", F));
+ BasicBlock *Body(BasicBlock::Create(C, "body", F));
+ BasicBlock *Exit(BasicBlock::Create(C, "exit", F));
+
+ B.SetInsertPoint(Entry);
+ Value *Alloca = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A");
+ BranchInst::Create(Header, Entry);
+
+ B.SetInsertPoint(Header);
+ StoreInst *S1 = B.CreateStore(B.getInt8(16), PointerArg);
+ B.CreateCondBr(B.getTrue(), Exit, Body);
+
+ B.SetInsertPoint(Body);
+ B.CreateStore(ConstantInt::get(Int8, 0), Alloca);
+ BranchInst::Create(Exit, Body);
+
+ B.SetInsertPoint(Exit);
+ StoreInst *S2 = B.CreateStore(B.getInt8(16), PointerArg);
+
+ setupAnalyses();
+ MemorySSA &MSSA = *Analyses->MSSA;
+ MemorySSAWalker *Walker = Analyses->Walker;
+ std::unique_ptr<MemorySSAUpdater> MSSAU =
+ make_unique<MemorySSAUpdater>(&MSSA);
+
+ MemoryDef *DefS1 = cast<MemoryDef>(MSSA.getMemoryAccess(S1));
+ EXPECT_EQ(DefS1, Walker->getClobberingMemoryAccess(S2));
+
+ // Alter CFG, add edge: entry -> exit
+ Entry->getTerminator()->eraseFromParent();
+ B.SetInsertPoint(Entry);
+ B.CreateCondBr(B.getTrue(), Header, Exit);
+ SmallVector<CFGUpdate, 1> Updates;
+ Updates.push_back({cfg::UpdateKind::Insert, Entry, Exit});
+ Analyses->DT.applyUpdates(Updates);
+ MSSAU->applyInsertUpdates(Updates, Analyses->DT);
+
+ MemoryPhi *Phi = MSSA.getMemoryAccess(Exit);
+ EXPECT_EQ(Phi, Walker->getClobberingMemoryAccess(S2));
+}
+
+// entry
+// / |
+// a |
+// / \ |
+// b c f
+// \ / |
+// d |
+// \ /
+// e
+// f:
+// ; 1 = MemoryDef(liveOnEntry)
+// e:
+// ; 2 = MemoryPhi({d, liveOnEntry}, {f, 1})
+//
+// Insert edge: f -> c, check update is correct.
+// After update:
+// f:
+// ; 1 = MemoryDef(liveOnEntry)
+// c:
+// ; 3 = MemoryPhi({a, liveOnEntry}, {f, 1})
+// d:
+// ; 4 = MemoryPhi({b, liveOnEntry}, {c, 3})
+// e:
+// ; 2 = MemoryPhi({d, 4}, {f, 1})
+TEST_F(MemorySSATest, TestAddedEdgeToBlockWithNoPhiAddNewPhis) {
+ F = Function::Create(
+ FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
+ GlobalValue::ExternalLinkage, "F", &M);
+ Argument *PointerArg = &*F->arg_begin();
+ BasicBlock *Entry(BasicBlock::Create(C, "entry", F));
+ BasicBlock *ABlock(BasicBlock::Create(C, "a", F));
+ BasicBlock *BBlock(BasicBlock::Create(C, "b", F));
+ BasicBlock *CBlock(BasicBlock::Create(C, "c", F));
+ BasicBlock *DBlock(BasicBlock::Create(C, "d", F));
+ BasicBlock *EBlock(BasicBlock::Create(C, "e", F));
+ BasicBlock *FBlock(BasicBlock::Create(C, "f", F));
+
+ B.SetInsertPoint(Entry);
+ B.CreateCondBr(B.getTrue(), ABlock, FBlock);
+ B.SetInsertPoint(ABlock);
+ B.CreateCondBr(B.getTrue(), BBlock, CBlock);
+ B.SetInsertPoint(BBlock);
+ BranchInst::Create(DBlock, BBlock);
+ B.SetInsertPoint(CBlock);
+ BranchInst::Create(DBlock, CBlock);
+ B.SetInsertPoint(DBlock);
+ BranchInst::Create(EBlock, DBlock);
+ B.SetInsertPoint(FBlock);
+ B.CreateStore(B.getInt8(16), PointerArg);
+ BranchInst::Create(EBlock, FBlock);
+
+ setupAnalyses();
+ MemorySSA &MSSA = *Analyses->MSSA;
+ std::unique_ptr<MemorySSAUpdater> MSSAU =
+ make_unique<MemorySSAUpdater>(&MSSA);
+
+ // Alter CFG, add edge: f -> c
+ FBlock->getTerminator()->eraseFromParent();
+ B.SetInsertPoint(FBlock);
+ B.CreateCondBr(B.getTrue(), CBlock, EBlock);
+ SmallVector<CFGUpdate, 1> Updates;
+ Updates.push_back({cfg::UpdateKind::Insert, FBlock, CBlock});
+ Analyses->DT.applyUpdates(Updates);
+ MSSAU->applyInsertUpdates(Updates, Analyses->DT);
+
+ MemoryPhi *MPC = MSSA.getMemoryAccess(CBlock);
+ EXPECT_NE(MPC, nullptr);
+ MemoryPhi *MPD = MSSA.getMemoryAccess(DBlock);
+ EXPECT_NE(MPD, nullptr);
+ MemoryPhi *MPE = MSSA.getMemoryAccess(EBlock);
+ EXPECT_EQ(MPD, MPE->getIncomingValueForBlock(DBlock));
+}
OpenPOWER on IntegriCloud