1 //===- MemorySSA.cpp - Unit tests for MemorySSA ---------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 #include "llvm/Analysis/MemorySSA.h"
9 #include "llvm/Analysis/AliasAnalysis.h"
10 #include "llvm/Analysis/AssumptionCache.h"
11 #include "llvm/Analysis/BasicAliasAnalysis.h"
12 #include "llvm/Analysis/MemorySSAUpdater.h"
13 #include "llvm/Analysis/TargetLibraryInfo.h"
14 #include "llvm/IR/BasicBlock.h"
15 #include "llvm/IR/DataLayout.h"
16 #include "llvm/IR/Dominators.h"
17 #include "llvm/IR/IRBuilder.h"
18 #include "llvm/IR/Instructions.h"
19 #include "llvm/IR/LLVMContext.h"
20 #include "gtest/gtest.h"
21
22 using namespace llvm;
23
24 const static char DLString[] = "e-i64:64-f80:128-n8:16:32:64-S128";
25
26 /// There's a lot of common setup between these tests. This fixture helps reduce
27 /// that. Tests should mock up a function, store it in F, and then call
28 /// setupAnalyses().
29 class MemorySSATest : public testing::Test {
30 protected:
31 // N.B. Many of these members depend on each other (e.g. the Module depends on
32 // the Context, etc.). So, order matters here (and in TestAnalyses).
33 LLVMContext C;
34 Module M;
35 IRBuilder<> B;
36 DataLayout DL;
37 TargetLibraryInfoImpl TLII;
38 TargetLibraryInfo TLI;
39 Function *F;
40
41 // Things that we need to build after the function is created.
42 struct TestAnalyses {
43 DominatorTree DT;
44 AssumptionCache AC;
45 AAResults AA;
46 BasicAAResult BAA;
47 // We need to defer MSSA construction until AA is *entirely* set up, which
48 // requires calling addAAResult. Hence, we just use a pointer here.
49 std::unique_ptr<MemorySSA> MSSA;
50 MemorySSAWalker *Walker;
51
TestAnalysesMemorySSATest::TestAnalyses52 TestAnalyses(MemorySSATest &Test)
53 : DT(*Test.F), AC(*Test.F), AA(Test.TLI),
54 BAA(Test.DL, *Test.F, Test.TLI, AC, &DT) {
55 AA.addAAResult(BAA);
56 MSSA = std::make_unique<MemorySSA>(*Test.F, &AA, &DT);
57 Walker = MSSA->getWalker();
58 }
59 };
60
61 std::unique_ptr<TestAnalyses> Analyses;
62
setupAnalyses()63 void setupAnalyses() {
64 assert(F);
65 Analyses.reset(new TestAnalyses(*this));
66 }
67
68 public:
MemorySSATest()69 MemorySSATest()
70 : M("MemorySSATest", C), B(C), DL(DLString), TLI(TLII), F(nullptr) {}
71 };
72
TEST_F(MemorySSATest,CreateALoad)73 TEST_F(MemorySSATest, CreateALoad) {
74 // We create a diamond where there is a store on one side, and then after
75 // building MemorySSA, create a load after the merge point, and use it to test
76 // updating by creating an access for the load.
77 F = Function::Create(
78 FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
79 GlobalValue::ExternalLinkage, "F", &M);
80 BasicBlock *Entry(BasicBlock::Create(C, "", F));
81 BasicBlock *Left(BasicBlock::Create(C, "", F));
82 BasicBlock *Right(BasicBlock::Create(C, "", F));
83 BasicBlock *Merge(BasicBlock::Create(C, "", F));
84 B.SetInsertPoint(Entry);
85 B.CreateCondBr(B.getTrue(), Left, Right);
86 B.SetInsertPoint(Left);
87 Argument *PointerArg = &*F->arg_begin();
88 B.CreateStore(B.getInt8(16), PointerArg);
89 BranchInst::Create(Merge, Left);
90 BranchInst::Create(Merge, Right);
91
92 setupAnalyses();
93 MemorySSA &MSSA = *Analyses->MSSA;
94 MemorySSAUpdater Updater(&MSSA);
95 // Add the load
96 B.SetInsertPoint(Merge);
97 LoadInst *LoadInst = B.CreateLoad(B.getInt8Ty(), PointerArg);
98
99 // MemoryPHI should already exist.
100 MemoryPhi *MP = MSSA.getMemoryAccess(Merge);
101 EXPECT_NE(MP, nullptr);
102
103 // Create the load memory acccess
104 MemoryUse *LoadAccess = cast<MemoryUse>(Updater.createMemoryAccessInBB(
105 LoadInst, MP, Merge, MemorySSA::Beginning));
106 MemoryAccess *DefiningAccess = LoadAccess->getDefiningAccess();
107 EXPECT_TRUE(isa<MemoryPhi>(DefiningAccess));
108 MSSA.verifyMemorySSA();
109 }
TEST_F(MemorySSATest,CreateLoadsAndStoreUpdater)110 TEST_F(MemorySSATest, CreateLoadsAndStoreUpdater) {
111 // We create a diamond, then build memoryssa with no memory accesses, and
112 // incrementally update it by inserting a store in the, entry, a load in the
113 // merge point, then a store in the branch, another load in the merge point,
114 // and then a store in the entry.
115 F = Function::Create(
116 FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
117 GlobalValue::ExternalLinkage, "F", &M);
118 BasicBlock *Entry(BasicBlock::Create(C, "", F));
119 BasicBlock *Left(BasicBlock::Create(C, "", F));
120 BasicBlock *Right(BasicBlock::Create(C, "", F));
121 BasicBlock *Merge(BasicBlock::Create(C, "", F));
122 B.SetInsertPoint(Entry);
123 B.CreateCondBr(B.getTrue(), Left, Right);
124 B.SetInsertPoint(Left, Left->begin());
125 Argument *PointerArg = &*F->arg_begin();
126 B.SetInsertPoint(Left);
127 B.CreateBr(Merge);
128 B.SetInsertPoint(Right);
129 B.CreateBr(Merge);
130
131 setupAnalyses();
132 MemorySSA &MSSA = *Analyses->MSSA;
133 MemorySSAUpdater Updater(&MSSA);
134 // Add the store
135 B.SetInsertPoint(Entry, Entry->begin());
136 StoreInst *EntryStore = B.CreateStore(B.getInt8(16), PointerArg);
137 MemoryAccess *EntryStoreAccess = Updater.createMemoryAccessInBB(
138 EntryStore, nullptr, Entry, MemorySSA::Beginning);
139 Updater.insertDef(cast<MemoryDef>(EntryStoreAccess));
140
141 // Add the load
142 B.SetInsertPoint(Merge, Merge->begin());
143 LoadInst *FirstLoad = B.CreateLoad(B.getInt8Ty(), PointerArg);
144
145 // MemoryPHI should not already exist.
146 MemoryPhi *MP = MSSA.getMemoryAccess(Merge);
147 EXPECT_EQ(MP, nullptr);
148
149 // Create the load memory access
150 MemoryUse *FirstLoadAccess = cast<MemoryUse>(Updater.createMemoryAccessInBB(
151 FirstLoad, nullptr, Merge, MemorySSA::Beginning));
152 Updater.insertUse(FirstLoadAccess);
153 // Should just have a load using the entry access, because it should discover
154 // the phi is trivial
155 EXPECT_EQ(FirstLoadAccess->getDefiningAccess(), EntryStoreAccess);
156
157 // Create a store on the left
158 // Add the store
159 B.SetInsertPoint(Left, Left->begin());
160 StoreInst *LeftStore = B.CreateStore(B.getInt8(16), PointerArg);
161 MemoryAccess *LeftStoreAccess = Updater.createMemoryAccessInBB(
162 LeftStore, nullptr, Left, MemorySSA::Beginning);
163 Updater.insertDef(cast<MemoryDef>(LeftStoreAccess), false);
164
165 // MemoryPHI should exist after adding LeftStore.
166 MP = MSSA.getMemoryAccess(Merge);
167 EXPECT_NE(MP, nullptr);
168
169 // Add the second load
170 B.SetInsertPoint(Merge, Merge->begin());
171 LoadInst *SecondLoad = B.CreateLoad(B.getInt8Ty(), PointerArg);
172
173 // Create the load memory access
174 MemoryUse *SecondLoadAccess = cast<MemoryUse>(Updater.createMemoryAccessInBB(
175 SecondLoad, nullptr, Merge, MemorySSA::Beginning));
176 Updater.insertUse(SecondLoadAccess);
177 // Now the load should be a phi of the entry store and the left store
178 MemoryPhi *MergePhi =
179 dyn_cast<MemoryPhi>(SecondLoadAccess->getDefiningAccess());
180 EXPECT_NE(MergePhi, nullptr);
181 EXPECT_EQ(MergePhi->getIncomingValue(0), EntryStoreAccess);
182 EXPECT_EQ(MergePhi->getIncomingValue(1), LeftStoreAccess);
183 // Now create a store below the existing one in the entry
184 B.SetInsertPoint(Entry, --Entry->end());
185 StoreInst *SecondEntryStore = B.CreateStore(B.getInt8(16), PointerArg);
186 MemoryAccess *SecondEntryStoreAccess = Updater.createMemoryAccessInBB(
187 SecondEntryStore, nullptr, Entry, MemorySSA::End);
188 // Insert it twice just to test renaming
189 Updater.insertDef(cast<MemoryDef>(SecondEntryStoreAccess), false);
190 EXPECT_NE(FirstLoadAccess->getDefiningAccess(), MergePhi);
191 Updater.insertDef(cast<MemoryDef>(SecondEntryStoreAccess), true);
192 EXPECT_EQ(FirstLoadAccess->getDefiningAccess(), MergePhi);
193 // and make sure the phi below it got updated, despite being blocks away
194 MergePhi = dyn_cast<MemoryPhi>(SecondLoadAccess->getDefiningAccess());
195 EXPECT_NE(MergePhi, nullptr);
196 EXPECT_EQ(MergePhi->getIncomingValue(0), SecondEntryStoreAccess);
197 EXPECT_EQ(MergePhi->getIncomingValue(1), LeftStoreAccess);
198 MSSA.verifyMemorySSA();
199 }
200
TEST_F(MemorySSATest,CreateALoadUpdater)201 TEST_F(MemorySSATest, CreateALoadUpdater) {
202 // We create a diamond, then build memoryssa with no memory accesses, and
203 // incrementally update it by inserting a store in one of the branches, and a
204 // load in the merge point
205 F = Function::Create(
206 FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
207 GlobalValue::ExternalLinkage, "F", &M);
208 BasicBlock *Entry(BasicBlock::Create(C, "", F));
209 BasicBlock *Left(BasicBlock::Create(C, "", F));
210 BasicBlock *Right(BasicBlock::Create(C, "", F));
211 BasicBlock *Merge(BasicBlock::Create(C, "", F));
212 B.SetInsertPoint(Entry);
213 B.CreateCondBr(B.getTrue(), Left, Right);
214 B.SetInsertPoint(Left, Left->begin());
215 Argument *PointerArg = &*F->arg_begin();
216 B.SetInsertPoint(Left);
217 B.CreateBr(Merge);
218 B.SetInsertPoint(Right);
219 B.CreateBr(Merge);
220
221 setupAnalyses();
222 MemorySSA &MSSA = *Analyses->MSSA;
223 MemorySSAUpdater Updater(&MSSA);
224 B.SetInsertPoint(Left, Left->begin());
225 // Add the store
226 StoreInst *SI = B.CreateStore(B.getInt8(16), PointerArg);
227 MemoryAccess *StoreAccess =
228 Updater.createMemoryAccessInBB(SI, nullptr, Left, MemorySSA::Beginning);
229 Updater.insertDef(cast<MemoryDef>(StoreAccess));
230
231 // MemoryPHI should be created when inserting the def
232 MemoryPhi *MP = MSSA.getMemoryAccess(Merge);
233 EXPECT_NE(MP, nullptr);
234
235 // Add the load
236 B.SetInsertPoint(Merge, Merge->begin());
237 LoadInst *LoadInst = B.CreateLoad(B.getInt8Ty(), PointerArg);
238
239 // Create the load memory acccess
240 MemoryUse *LoadAccess = cast<MemoryUse>(Updater.createMemoryAccessInBB(
241 LoadInst, nullptr, Merge, MemorySSA::Beginning));
242 Updater.insertUse(LoadAccess);
243 MemoryAccess *DefiningAccess = LoadAccess->getDefiningAccess();
244 EXPECT_TRUE(isa<MemoryPhi>(DefiningAccess));
245 MSSA.verifyMemorySSA();
246 }
247
TEST_F(MemorySSATest,SinkLoad)248 TEST_F(MemorySSATest, SinkLoad) {
249 F = Function::Create(
250 FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
251 GlobalValue::ExternalLinkage, "F", &M);
252 BasicBlock *Entry(BasicBlock::Create(C, "", F));
253 BasicBlock *Left(BasicBlock::Create(C, "", F));
254 BasicBlock *Right(BasicBlock::Create(C, "", F));
255 BasicBlock *Merge(BasicBlock::Create(C, "", F));
256 B.SetInsertPoint(Entry);
257 B.CreateCondBr(B.getTrue(), Left, Right);
258 B.SetInsertPoint(Left, Left->begin());
259 Argument *PointerArg = &*F->arg_begin();
260 B.SetInsertPoint(Left);
261 B.CreateBr(Merge);
262 B.SetInsertPoint(Right);
263 B.CreateBr(Merge);
264
265 // Load in left block
266 B.SetInsertPoint(Left, Left->begin());
267 LoadInst *LoadInst1 = B.CreateLoad(B.getInt8Ty(), PointerArg);
268 // Store in merge block
269 B.SetInsertPoint(Merge, Merge->begin());
270 B.CreateStore(B.getInt8(16), PointerArg);
271
272 setupAnalyses();
273 MemorySSA &MSSA = *Analyses->MSSA;
274 MemorySSAUpdater Updater(&MSSA);
275
276 // Mimic sinking of a load:
277 // - clone load
278 // - insert in "exit" block
279 // - insert in mssa
280 // - remove from original block
281
282 LoadInst *LoadInstClone = cast<LoadInst>(LoadInst1->clone());
283 Merge->getInstList().insert(Merge->begin(), LoadInstClone);
284 MemoryAccess * NewLoadAccess =
285 Updater.createMemoryAccessInBB(LoadInstClone, nullptr,
286 LoadInstClone->getParent(),
287 MemorySSA::Beginning);
288 Updater.insertUse(cast<MemoryUse>(NewLoadAccess));
289 MSSA.verifyMemorySSA();
290 Updater.removeMemoryAccess(MSSA.getMemoryAccess(LoadInst1));
291 MSSA.verifyMemorySSA();
292 }
293
TEST_F(MemorySSATest,MoveAStore)294 TEST_F(MemorySSATest, MoveAStore) {
295 // We create a diamond where there is a in the entry, a store on one side, and
296 // a load at the end. After building MemorySSA, we test updating by moving
297 // the store from the side block to the entry block. This destroys the old
298 // access.
299 F = Function::Create(
300 FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
301 GlobalValue::ExternalLinkage, "F", &M);
302 BasicBlock *Entry(BasicBlock::Create(C, "", F));
303 BasicBlock *Left(BasicBlock::Create(C, "", F));
304 BasicBlock *Right(BasicBlock::Create(C, "", F));
305 BasicBlock *Merge(BasicBlock::Create(C, "", F));
306 B.SetInsertPoint(Entry);
307 Argument *PointerArg = &*F->arg_begin();
308 StoreInst *EntryStore = B.CreateStore(B.getInt8(16), PointerArg);
309 B.CreateCondBr(B.getTrue(), Left, Right);
310 B.SetInsertPoint(Left);
311 StoreInst *SideStore = B.CreateStore(B.getInt8(16), PointerArg);
312 BranchInst::Create(Merge, Left);
313 BranchInst::Create(Merge, Right);
314 B.SetInsertPoint(Merge);
315 B.CreateLoad(B.getInt8Ty(), PointerArg);
316 setupAnalyses();
317 MemorySSA &MSSA = *Analyses->MSSA;
318 MemorySSAUpdater Updater(&MSSA);
319 // Move the store
320 SideStore->moveBefore(Entry->getTerminator());
321 MemoryAccess *EntryStoreAccess = MSSA.getMemoryAccess(EntryStore);
322 MemoryAccess *SideStoreAccess = MSSA.getMemoryAccess(SideStore);
323 MemoryAccess *NewStoreAccess = Updater.createMemoryAccessAfter(
324 SideStore, EntryStoreAccess, EntryStoreAccess);
325 EntryStoreAccess->replaceAllUsesWith(NewStoreAccess);
326 Updater.removeMemoryAccess(SideStoreAccess);
327 MSSA.verifyMemorySSA();
328 }
329
TEST_F(MemorySSATest,MoveAStoreUpdater)330 TEST_F(MemorySSATest, MoveAStoreUpdater) {
331 // We create a diamond where there is a in the entry, a store on one side, and
332 // a load at the end. After building MemorySSA, we test updating by moving
333 // the store from the side block to the entry block. This destroys the old
334 // access.
335 F = Function::Create(
336 FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
337 GlobalValue::ExternalLinkage, "F", &M);
338 BasicBlock *Entry(BasicBlock::Create(C, "", F));
339 BasicBlock *Left(BasicBlock::Create(C, "", F));
340 BasicBlock *Right(BasicBlock::Create(C, "", F));
341 BasicBlock *Merge(BasicBlock::Create(C, "", F));
342 B.SetInsertPoint(Entry);
343 Argument *PointerArg = &*F->arg_begin();
344 StoreInst *EntryStore = B.CreateStore(B.getInt8(16), PointerArg);
345 B.CreateCondBr(B.getTrue(), Left, Right);
346 B.SetInsertPoint(Left);
347 auto *SideStore = B.CreateStore(B.getInt8(16), PointerArg);
348 BranchInst::Create(Merge, Left);
349 BranchInst::Create(Merge, Right);
350 B.SetInsertPoint(Merge);
351 auto *MergeLoad = B.CreateLoad(B.getInt8Ty(), PointerArg);
352 setupAnalyses();
353 MemorySSA &MSSA = *Analyses->MSSA;
354 MemorySSAUpdater Updater(&MSSA);
355
356 // Move the store
357 SideStore->moveBefore(Entry->getTerminator());
358 auto *EntryStoreAccess = MSSA.getMemoryAccess(EntryStore);
359 auto *SideStoreAccess = MSSA.getMemoryAccess(SideStore);
360 auto *NewStoreAccess = Updater.createMemoryAccessAfter(
361 SideStore, EntryStoreAccess, EntryStoreAccess);
362 // Before, the load will point to a phi of the EntryStore and SideStore.
363 auto *LoadAccess = cast<MemoryUse>(MSSA.getMemoryAccess(MergeLoad));
364 EXPECT_TRUE(isa<MemoryPhi>(LoadAccess->getDefiningAccess()));
365 MemoryPhi *MergePhi = cast<MemoryPhi>(LoadAccess->getDefiningAccess());
366 EXPECT_EQ(MergePhi->getIncomingValue(1), EntryStoreAccess);
367 EXPECT_EQ(MergePhi->getIncomingValue(0), SideStoreAccess);
368 Updater.removeMemoryAccess(SideStoreAccess);
369 Updater.insertDef(cast<MemoryDef>(NewStoreAccess));
370 // After it's a phi of the new side store access.
371 EXPECT_EQ(MergePhi->getIncomingValue(0), NewStoreAccess);
372 EXPECT_EQ(MergePhi->getIncomingValue(1), NewStoreAccess);
373 MSSA.verifyMemorySSA();
374 }
375
TEST_F(MemorySSATest,MoveAStoreUpdaterMove)376 TEST_F(MemorySSATest, MoveAStoreUpdaterMove) {
377 // We create a diamond where there is a in the entry, a store on one side, and
378 // a load at the end. After building MemorySSA, we test updating by moving
379 // the store from the side block to the entry block. This does not destroy
380 // the old access.
381 F = Function::Create(
382 FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
383 GlobalValue::ExternalLinkage, "F", &M);
384 BasicBlock *Entry(BasicBlock::Create(C, "", F));
385 BasicBlock *Left(BasicBlock::Create(C, "", F));
386 BasicBlock *Right(BasicBlock::Create(C, "", F));
387 BasicBlock *Merge(BasicBlock::Create(C, "", F));
388 B.SetInsertPoint(Entry);
389 Argument *PointerArg = &*F->arg_begin();
390 StoreInst *EntryStore = B.CreateStore(B.getInt8(16), PointerArg);
391 B.CreateCondBr(B.getTrue(), Left, Right);
392 B.SetInsertPoint(Left);
393 auto *SideStore = B.CreateStore(B.getInt8(16), PointerArg);
394 BranchInst::Create(Merge, Left);
395 BranchInst::Create(Merge, Right);
396 B.SetInsertPoint(Merge);
397 auto *MergeLoad = B.CreateLoad(B.getInt8Ty(), PointerArg);
398 setupAnalyses();
399 MemorySSA &MSSA = *Analyses->MSSA;
400 MemorySSAUpdater Updater(&MSSA);
401
402 // Move the store
403 auto *EntryStoreAccess = MSSA.getMemoryAccess(EntryStore);
404 auto *SideStoreAccess = MSSA.getMemoryAccess(SideStore);
405 // Before, the load will point to a phi of the EntryStore and SideStore.
406 auto *LoadAccess = cast<MemoryUse>(MSSA.getMemoryAccess(MergeLoad));
407 EXPECT_TRUE(isa<MemoryPhi>(LoadAccess->getDefiningAccess()));
408 MemoryPhi *MergePhi = cast<MemoryPhi>(LoadAccess->getDefiningAccess());
409 EXPECT_EQ(MergePhi->getIncomingValue(1), EntryStoreAccess);
410 EXPECT_EQ(MergePhi->getIncomingValue(0), SideStoreAccess);
411 SideStore->moveBefore(*EntryStore->getParent(), ++EntryStore->getIterator());
412 Updater.moveAfter(SideStoreAccess, EntryStoreAccess);
413 // After, it's a phi of the side store.
414 EXPECT_EQ(MergePhi->getIncomingValue(0), SideStoreAccess);
415 EXPECT_EQ(MergePhi->getIncomingValue(1), SideStoreAccess);
416
417 MSSA.verifyMemorySSA();
418 }
419
TEST_F(MemorySSATest,MoveAStoreAllAround)420 TEST_F(MemorySSATest, MoveAStoreAllAround) {
421 // We create a diamond where there is a in the entry, a store on one side, and
422 // a load at the end. After building MemorySSA, we test updating by moving
423 // the store from the side block to the entry block, then to the other side
424 // block, then to before the load. This does not destroy the old access.
425 F = Function::Create(
426 FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
427 GlobalValue::ExternalLinkage, "F", &M);
428 BasicBlock *Entry(BasicBlock::Create(C, "", F));
429 BasicBlock *Left(BasicBlock::Create(C, "", F));
430 BasicBlock *Right(BasicBlock::Create(C, "", F));
431 BasicBlock *Merge(BasicBlock::Create(C, "", F));
432 B.SetInsertPoint(Entry);
433 Argument *PointerArg = &*F->arg_begin();
434 StoreInst *EntryStore = B.CreateStore(B.getInt8(16), PointerArg);
435 B.CreateCondBr(B.getTrue(), Left, Right);
436 B.SetInsertPoint(Left);
437 auto *SideStore = B.CreateStore(B.getInt8(16), PointerArg);
438 BranchInst::Create(Merge, Left);
439 BranchInst::Create(Merge, Right);
440 B.SetInsertPoint(Merge);
441 auto *MergeLoad = B.CreateLoad(B.getInt8Ty(), PointerArg);
442 setupAnalyses();
443 MemorySSA &MSSA = *Analyses->MSSA;
444 MemorySSAUpdater Updater(&MSSA);
445
446 // Move the store
447 auto *EntryStoreAccess = MSSA.getMemoryAccess(EntryStore);
448 auto *SideStoreAccess = MSSA.getMemoryAccess(SideStore);
449 // Before, the load will point to a phi of the EntryStore and SideStore.
450 auto *LoadAccess = cast<MemoryUse>(MSSA.getMemoryAccess(MergeLoad));
451 EXPECT_TRUE(isa<MemoryPhi>(LoadAccess->getDefiningAccess()));
452 MemoryPhi *MergePhi = cast<MemoryPhi>(LoadAccess->getDefiningAccess());
453 EXPECT_EQ(MergePhi->getIncomingValue(1), EntryStoreAccess);
454 EXPECT_EQ(MergePhi->getIncomingValue(0), SideStoreAccess);
455 // Move the store before the entry store
456 SideStore->moveBefore(*EntryStore->getParent(), EntryStore->getIterator());
457 Updater.moveBefore(SideStoreAccess, EntryStoreAccess);
458 // After, it's a phi of the entry store.
459 EXPECT_EQ(MergePhi->getIncomingValue(0), EntryStoreAccess);
460 EXPECT_EQ(MergePhi->getIncomingValue(1), EntryStoreAccess);
461 MSSA.verifyMemorySSA();
462 // Now move the store to the right branch
463 SideStore->moveBefore(*Right, Right->begin());
464 Updater.moveToPlace(SideStoreAccess, Right, MemorySSA::Beginning);
465 MSSA.verifyMemorySSA();
466 EXPECT_EQ(MergePhi->getIncomingValue(0), EntryStoreAccess);
467 EXPECT_EQ(MergePhi->getIncomingValue(1), SideStoreAccess);
468 // Now move it before the load
469 SideStore->moveBefore(MergeLoad);
470 Updater.moveBefore(SideStoreAccess, LoadAccess);
471 EXPECT_EQ(MergePhi->getIncomingValue(0), EntryStoreAccess);
472 EXPECT_EQ(MergePhi->getIncomingValue(1), EntryStoreAccess);
473 MSSA.verifyMemorySSA();
474 }
475
TEST_F(MemorySSATest,RemoveAPhi)476 TEST_F(MemorySSATest, RemoveAPhi) {
477 // We create a diamond where there is a store on one side, and then a load
478 // after the merge point. This enables us to test a bunch of different
479 // removal cases.
480 F = Function::Create(
481 FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
482 GlobalValue::ExternalLinkage, "F", &M);
483 BasicBlock *Entry(BasicBlock::Create(C, "", F));
484 BasicBlock *Left(BasicBlock::Create(C, "", F));
485 BasicBlock *Right(BasicBlock::Create(C, "", F));
486 BasicBlock *Merge(BasicBlock::Create(C, "", F));
487 B.SetInsertPoint(Entry);
488 B.CreateCondBr(B.getTrue(), Left, Right);
489 B.SetInsertPoint(Left);
490 Argument *PointerArg = &*F->arg_begin();
491 StoreInst *StoreInst = B.CreateStore(B.getInt8(16), PointerArg);
492 BranchInst::Create(Merge, Left);
493 BranchInst::Create(Merge, Right);
494 B.SetInsertPoint(Merge);
495 LoadInst *LoadInst = B.CreateLoad(B.getInt8Ty(), PointerArg);
496
497 setupAnalyses();
498 MemorySSA &MSSA = *Analyses->MSSA;
499 MemorySSAUpdater Updater(&MSSA);
500
501 // Before, the load will be a use of a phi<store, liveonentry>.
502 MemoryUse *LoadAccess = cast<MemoryUse>(MSSA.getMemoryAccess(LoadInst));
503 MemoryDef *StoreAccess = cast<MemoryDef>(MSSA.getMemoryAccess(StoreInst));
504 MemoryAccess *DefiningAccess = LoadAccess->getDefiningAccess();
505 EXPECT_TRUE(isa<MemoryPhi>(DefiningAccess));
506 // Kill the store
507 Updater.removeMemoryAccess(StoreAccess);
508 MemoryPhi *MP = cast<MemoryPhi>(DefiningAccess);
509 // Verify the phi ended up as liveonentry, liveonentry
510 for (auto &Op : MP->incoming_values())
511 EXPECT_TRUE(MSSA.isLiveOnEntryDef(cast<MemoryAccess>(Op.get())));
512 // Replace the phi uses with the live on entry def
513 MP->replaceAllUsesWith(MSSA.getLiveOnEntryDef());
514 // Verify the load is now defined by liveOnEntryDef
515 EXPECT_TRUE(MSSA.isLiveOnEntryDef(LoadAccess->getDefiningAccess()));
516 // Remove the PHI
517 Updater.removeMemoryAccess(MP);
518 MSSA.verifyMemorySSA();
519 }
520
TEST_F(MemorySSATest,RemoveMemoryAccess)521 TEST_F(MemorySSATest, RemoveMemoryAccess) {
522 // We create a diamond where there is a store on one side, and then a load
523 // after the merge point. This enables us to test a bunch of different
524 // removal cases.
525 F = Function::Create(
526 FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
527 GlobalValue::ExternalLinkage, "F", &M);
528 BasicBlock *Entry(BasicBlock::Create(C, "", F));
529 BasicBlock *Left(BasicBlock::Create(C, "", F));
530 BasicBlock *Right(BasicBlock::Create(C, "", F));
531 BasicBlock *Merge(BasicBlock::Create(C, "", F));
532 B.SetInsertPoint(Entry);
533 B.CreateCondBr(B.getTrue(), Left, Right);
534 B.SetInsertPoint(Left);
535 Argument *PointerArg = &*F->arg_begin();
536 StoreInst *StoreInst = B.CreateStore(B.getInt8(16), PointerArg);
537 BranchInst::Create(Merge, Left);
538 BranchInst::Create(Merge, Right);
539 B.SetInsertPoint(Merge);
540 LoadInst *LoadInst = B.CreateLoad(B.getInt8Ty(), PointerArg);
541
542 setupAnalyses();
543 MemorySSA &MSSA = *Analyses->MSSA;
544 MemorySSAWalker *Walker = Analyses->Walker;
545 MemorySSAUpdater Updater(&MSSA);
546
547 // Before, the load will be a use of a phi<store, liveonentry>. It should be
548 // the same after.
549 MemoryUse *LoadAccess = cast<MemoryUse>(MSSA.getMemoryAccess(LoadInst));
550 MemoryDef *StoreAccess = cast<MemoryDef>(MSSA.getMemoryAccess(StoreInst));
551 MemoryAccess *DefiningAccess = LoadAccess->getDefiningAccess();
552 EXPECT_TRUE(isa<MemoryPhi>(DefiningAccess));
553 // The load is currently clobbered by one of the phi arguments, so the walker
554 // should determine the clobbering access as the phi.
555 EXPECT_EQ(DefiningAccess, Walker->getClobberingMemoryAccess(LoadInst));
556 Updater.removeMemoryAccess(StoreAccess);
557 MSSA.verifyMemorySSA();
558 // After the removeaccess, let's see if we got the right accesses
559 // The load should still point to the phi ...
560 EXPECT_EQ(DefiningAccess, LoadAccess->getDefiningAccess());
561 // but we should now get live on entry for the clobbering definition of the
562 // load, since it will walk past the phi node since every argument is the
563 // same.
564 // XXX: This currently requires either removing the phi or resetting optimized
565 // on the load
566
567 EXPECT_FALSE(
568 MSSA.isLiveOnEntryDef(Walker->getClobberingMemoryAccess(LoadInst)));
569 // If we reset optimized, we get live on entry.
570 LoadAccess->resetOptimized();
571 EXPECT_TRUE(
572 MSSA.isLiveOnEntryDef(Walker->getClobberingMemoryAccess(LoadInst)));
573 // The phi should now be a two entry phi with two live on entry defs.
574 for (const auto &Op : DefiningAccess->operands()) {
575 MemoryAccess *Operand = cast<MemoryAccess>(&*Op);
576 EXPECT_TRUE(MSSA.isLiveOnEntryDef(Operand));
577 }
578
579 // Now we try to remove the single valued phi
580 Updater.removeMemoryAccess(DefiningAccess);
581 MSSA.verifyMemorySSA();
582 // Now the load should be a load of live on entry.
583 EXPECT_TRUE(MSSA.isLiveOnEntryDef(LoadAccess->getDefiningAccess()));
584 }
585
586 // We had a bug with caching where the walker would report MemoryDef#3's clobber
587 // (below) was MemoryDef#1.
588 //
589 // define void @F(i8*) {
590 // %A = alloca i8, i8 1
591 // ; 1 = MemoryDef(liveOnEntry)
592 // store i8 0, i8* %A
593 // ; 2 = MemoryDef(1)
594 // store i8 1, i8* %A
595 // ; 3 = MemoryDef(2)
596 // store i8 2, i8* %A
597 // }
TEST_F(MemorySSATest,TestTripleStore)598 TEST_F(MemorySSATest, TestTripleStore) {
599 F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false),
600 GlobalValue::ExternalLinkage, "F", &M);
601 B.SetInsertPoint(BasicBlock::Create(C, "", F));
602 Type *Int8 = Type::getInt8Ty(C);
603 Value *Alloca = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A");
604 StoreInst *S1 = B.CreateStore(ConstantInt::get(Int8, 0), Alloca);
605 StoreInst *S2 = B.CreateStore(ConstantInt::get(Int8, 1), Alloca);
606 StoreInst *S3 = B.CreateStore(ConstantInt::get(Int8, 2), Alloca);
607
608 setupAnalyses();
609 MemorySSA &MSSA = *Analyses->MSSA;
610 MemorySSAWalker *Walker = Analyses->Walker;
611
612 unsigned I = 0;
613 for (StoreInst *V : {S1, S2, S3}) {
614 // Everything should be clobbered by its defining access
615 MemoryAccess *DefiningAccess = MSSA.getMemoryAccess(V)->getDefiningAccess();
616 MemoryAccess *WalkerClobber = Walker->getClobberingMemoryAccess(V);
617 EXPECT_EQ(DefiningAccess, WalkerClobber)
618 << "Store " << I << " doesn't have the correct clobbering access";
619 // EXPECT_EQ expands such that if we increment I above, it won't get
620 // incremented except when we try to print the error message.
621 ++I;
622 }
623 }
624
625 // ...And fixing the above bug made it obvious that, when walking, MemorySSA's
626 // walker was caching the initial node it walked. This was fine (albeit
627 // mostly redundant) unless the initial node being walked is a clobber for the
628 // query. In that case, we'd cache that the node clobbered itself.
TEST_F(MemorySSATest,TestStoreAndLoad)629 TEST_F(MemorySSATest, TestStoreAndLoad) {
630 F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false),
631 GlobalValue::ExternalLinkage, "F", &M);
632 B.SetInsertPoint(BasicBlock::Create(C, "", F));
633 Type *Int8 = Type::getInt8Ty(C);
634 Value *Alloca = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A");
635 Instruction *SI = B.CreateStore(ConstantInt::get(Int8, 0), Alloca);
636 Instruction *LI = B.CreateLoad(Int8, Alloca);
637
638 setupAnalyses();
639 MemorySSA &MSSA = *Analyses->MSSA;
640 MemorySSAWalker *Walker = Analyses->Walker;
641
642 MemoryAccess *LoadClobber = Walker->getClobberingMemoryAccess(LI);
643 EXPECT_EQ(LoadClobber, MSSA.getMemoryAccess(SI));
644 EXPECT_TRUE(MSSA.isLiveOnEntryDef(Walker->getClobberingMemoryAccess(SI)));
645 }
646
647 // Another bug (related to the above two fixes): It was noted that, given the
648 // following code:
649 // ; 1 = MemoryDef(liveOnEntry)
650 // store i8 0, i8* %1
651 //
652 // ...A query to getClobberingMemoryAccess(MemoryAccess*, MemoryLocation) would
653 // hand back the store (correctly). A later call to
654 // getClobberingMemoryAccess(const Instruction*) would also hand back the store
655 // (incorrectly; it should return liveOnEntry).
656 //
657 // This test checks that repeated calls to either function returns what they're
658 // meant to.
TEST_F(MemorySSATest,TestStoreDoubleQuery)659 TEST_F(MemorySSATest, TestStoreDoubleQuery) {
660 F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false),
661 GlobalValue::ExternalLinkage, "F", &M);
662 B.SetInsertPoint(BasicBlock::Create(C, "", F));
663 Type *Int8 = Type::getInt8Ty(C);
664 Value *Alloca = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A");
665 StoreInst *SI = B.CreateStore(ConstantInt::get(Int8, 0), Alloca);
666
667 setupAnalyses();
668 MemorySSA &MSSA = *Analyses->MSSA;
669 MemorySSAWalker *Walker = Analyses->Walker;
670
671 MemoryAccess *StoreAccess = MSSA.getMemoryAccess(SI);
672 MemoryLocation StoreLoc = MemoryLocation::get(SI);
673 MemoryAccess *Clobber =
674 Walker->getClobberingMemoryAccess(StoreAccess, StoreLoc);
675 MemoryAccess *LiveOnEntry = Walker->getClobberingMemoryAccess(SI);
676
677 EXPECT_EQ(Clobber, StoreAccess);
678 EXPECT_TRUE(MSSA.isLiveOnEntryDef(LiveOnEntry));
679
680 // Try again (with entries in the cache already) for good measure...
681 Clobber = Walker->getClobberingMemoryAccess(StoreAccess, StoreLoc);
682 LiveOnEntry = Walker->getClobberingMemoryAccess(SI);
683 EXPECT_EQ(Clobber, StoreAccess);
684 EXPECT_TRUE(MSSA.isLiveOnEntryDef(LiveOnEntry));
685 }
686
687 // Bug: During phi optimization, the walker wouldn't cache to the proper result
688 // in the farthest-walked BB.
689 //
690 // Specifically, it would assume that whatever we walked to was a clobber.
691 // "Whatever we walked to" isn't a clobber if we hit a cache entry.
692 //
693 // ...So, we need a test case that looks like:
694 // A
695 // / \
696 // B |
697 // \ /
698 // C
699 //
700 // Where, when we try to optimize a thing in 'C', a blocker is found in 'B'.
701 // The walk must determine that the blocker exists by using cache entries *while
702 // walking* 'B'.
TEST_F(MemorySSATest,PartialWalkerCacheWithPhis)703 TEST_F(MemorySSATest, PartialWalkerCacheWithPhis) {
704 F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false),
705 GlobalValue::ExternalLinkage, "F", &M);
706 B.SetInsertPoint(BasicBlock::Create(C, "A", F));
707 Type *Int8 = Type::getInt8Ty(C);
708 Constant *One = ConstantInt::get(Int8, 1);
709 Constant *Zero = ConstantInt::get(Int8, 0);
710 Value *AllocA = B.CreateAlloca(Int8, One, "a");
711 Value *AllocB = B.CreateAlloca(Int8, One, "b");
712 BasicBlock *IfThen = BasicBlock::Create(C, "B", F);
713 BasicBlock *IfEnd = BasicBlock::Create(C, "C", F);
714
715 B.CreateCondBr(UndefValue::get(Type::getInt1Ty(C)), IfThen, IfEnd);
716
717 B.SetInsertPoint(IfThen);
718 Instruction *FirstStore = B.CreateStore(Zero, AllocA);
719 B.CreateStore(Zero, AllocB);
720 Instruction *ALoad0 = B.CreateLoad(Int8, AllocA, "");
721 Instruction *BStore = B.CreateStore(Zero, AllocB);
722 // Due to use optimization/etc. we make a store to A, which is removed after
723 // we build MSSA. This helps keep the test case simple-ish.
724 Instruction *KillStore = B.CreateStore(Zero, AllocA);
725 Instruction *ALoad = B.CreateLoad(Int8, AllocA, "");
726 B.CreateBr(IfEnd);
727
728 B.SetInsertPoint(IfEnd);
729 Instruction *BelowPhi = B.CreateStore(Zero, AllocA);
730
731 setupAnalyses();
732 MemorySSA &MSSA = *Analyses->MSSA;
733 MemorySSAWalker *Walker = Analyses->Walker;
734 MemorySSAUpdater Updater(&MSSA);
735
736 // Kill `KillStore`; it exists solely so that the load after it won't be
737 // optimized to FirstStore.
738 Updater.removeMemoryAccess(MSSA.getMemoryAccess(KillStore));
739 KillStore->eraseFromParent();
740 auto *ALoadMA = cast<MemoryUse>(MSSA.getMemoryAccess(ALoad));
741 EXPECT_EQ(ALoadMA->getDefiningAccess(), MSSA.getMemoryAccess(BStore));
742
743 // Populate the cache for the store to AllocB directly after FirstStore. It
744 // should point to something in block B (so something in D can't be optimized
745 // to it).
746 MemoryAccess *Load0Clobber = Walker->getClobberingMemoryAccess(ALoad0);
747 EXPECT_EQ(MSSA.getMemoryAccess(FirstStore), Load0Clobber);
748
749 // If the bug exists, this will introduce a bad cache entry for %a on BStore.
750 // It will point to the store to %b after FirstStore. This only happens during
751 // phi optimization.
752 MemoryAccess *BottomClobber = Walker->getClobberingMemoryAccess(BelowPhi);
753 MemoryAccess *Phi = MSSA.getMemoryAccess(IfEnd);
754 EXPECT_EQ(BottomClobber, Phi);
755
756 // This query will first check the cache for {%a, BStore}. It should point to
757 // FirstStore, not to the store after FirstStore.
758 MemoryAccess *UseClobber = Walker->getClobberingMemoryAccess(ALoad);
759 EXPECT_EQ(UseClobber, MSSA.getMemoryAccess(FirstStore));
760 }
761
762 // Test that our walker properly handles loads with the invariant group
763 // attribute. It's a bit hacky, since we add the invariant attribute *after*
764 // building MSSA. Otherwise, the use optimizer will optimize it for us, which
765 // isn't what we want.
766 // FIXME: It may be easier/cleaner to just add an 'optimize uses?' flag to MSSA.
TEST_F(MemorySSATest,WalkerInvariantLoadOpt)767 TEST_F(MemorySSATest, WalkerInvariantLoadOpt) {
768 F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false),
769 GlobalValue::ExternalLinkage, "F", &M);
770 B.SetInsertPoint(BasicBlock::Create(C, "", F));
771 Type *Int8 = Type::getInt8Ty(C);
772 Constant *One = ConstantInt::get(Int8, 1);
773 Value *AllocA = B.CreateAlloca(Int8, One, "");
774
775 Instruction *Store = B.CreateStore(One, AllocA);
776 Instruction *Load = B.CreateLoad(Int8, AllocA);
777
778 setupAnalyses();
779 MemorySSA &MSSA = *Analyses->MSSA;
780 MemorySSAWalker *Walker = Analyses->Walker;
781
782 auto *LoadMA = cast<MemoryUse>(MSSA.getMemoryAccess(Load));
783 auto *StoreMA = cast<MemoryDef>(MSSA.getMemoryAccess(Store));
784 EXPECT_EQ(LoadMA->getDefiningAccess(), StoreMA);
785
786 // ...At the time of writing, no cache should exist for LoadMA. Be a bit
787 // flexible to future changes.
788 Walker->invalidateInfo(LoadMA);
789 Load->setMetadata(LLVMContext::MD_invariant_load, MDNode::get(C, {}));
790
791 MemoryAccess *LoadClobber = Walker->getClobberingMemoryAccess(LoadMA);
792 EXPECT_EQ(LoadClobber, MSSA.getLiveOnEntryDef());
793 }
794
795 // Test loads get reoptimized properly by the walker.
TEST_F(MemorySSATest,WalkerReopt)796 TEST_F(MemorySSATest, WalkerReopt) {
797 F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false),
798 GlobalValue::ExternalLinkage, "F", &M);
799 B.SetInsertPoint(BasicBlock::Create(C, "", F));
800 Type *Int8 = Type::getInt8Ty(C);
801 Value *AllocaA = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A");
802 Instruction *SIA = B.CreateStore(ConstantInt::get(Int8, 0), AllocaA);
803 Value *AllocaB = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "B");
804 Instruction *SIB = B.CreateStore(ConstantInt::get(Int8, 0), AllocaB);
805 Instruction *LIA = B.CreateLoad(Int8, AllocaA);
806
807 setupAnalyses();
808 MemorySSA &MSSA = *Analyses->MSSA;
809 MemorySSAWalker *Walker = Analyses->Walker;
810 MemorySSAUpdater Updater(&MSSA);
811
812 MemoryAccess *LoadClobber = Walker->getClobberingMemoryAccess(LIA);
813 MemoryUse *LoadAccess = cast<MemoryUse>(MSSA.getMemoryAccess(LIA));
814 EXPECT_EQ(LoadClobber, MSSA.getMemoryAccess(SIA));
815 EXPECT_TRUE(MSSA.isLiveOnEntryDef(Walker->getClobberingMemoryAccess(SIA)));
816 Updater.removeMemoryAccess(LoadAccess);
817
818 // Create the load memory access pointing to an unoptimized place.
819 MemoryUse *NewLoadAccess = cast<MemoryUse>(Updater.createMemoryAccessInBB(
820 LIA, MSSA.getMemoryAccess(SIB), LIA->getParent(), MemorySSA::End));
821 // This should it cause it to be optimized
822 EXPECT_EQ(Walker->getClobberingMemoryAccess(NewLoadAccess), LoadClobber);
823 EXPECT_EQ(NewLoadAccess->getDefiningAccess(), LoadClobber);
824 }
825
826 // Test out MemorySSAUpdater::moveBefore
TEST_F(MemorySSATest,MoveAboveMemoryDef)827 TEST_F(MemorySSATest, MoveAboveMemoryDef) {
828 F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false),
829 GlobalValue::ExternalLinkage, "F", &M);
830 B.SetInsertPoint(BasicBlock::Create(C, "", F));
831
832 Type *Int8 = Type::getInt8Ty(C);
833 Value *A = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A");
834 Value *B_ = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "B");
835 Value *C = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "C");
836
837 StoreInst *StoreA0 = B.CreateStore(ConstantInt::get(Int8, 0), A);
838 StoreInst *StoreB = B.CreateStore(ConstantInt::get(Int8, 0), B_);
839 LoadInst *LoadB = B.CreateLoad(Int8, B_);
840 StoreInst *StoreA1 = B.CreateStore(ConstantInt::get(Int8, 4), A);
841 StoreInst *StoreC = B.CreateStore(ConstantInt::get(Int8, 4), C);
842 StoreInst *StoreA2 = B.CreateStore(ConstantInt::get(Int8, 4), A);
843 LoadInst *LoadC = B.CreateLoad(Int8, C);
844
845 setupAnalyses();
846 MemorySSA &MSSA = *Analyses->MSSA;
847 MemorySSAWalker &Walker = *Analyses->Walker;
848
849 MemorySSAUpdater Updater(&MSSA);
850 StoreC->moveBefore(StoreB);
851 Updater.moveBefore(cast<MemoryDef>(MSSA.getMemoryAccess(StoreC)),
852 cast<MemoryDef>(MSSA.getMemoryAccess(StoreB)));
853
854 MSSA.verifyMemorySSA();
855
856 EXPECT_EQ(MSSA.getMemoryAccess(StoreB)->getDefiningAccess(),
857 MSSA.getMemoryAccess(StoreC));
858 EXPECT_EQ(MSSA.getMemoryAccess(StoreC)->getDefiningAccess(),
859 MSSA.getMemoryAccess(StoreA0));
860 EXPECT_EQ(MSSA.getMemoryAccess(StoreA2)->getDefiningAccess(),
861 MSSA.getMemoryAccess(StoreA1));
862 EXPECT_EQ(Walker.getClobberingMemoryAccess(LoadB),
863 MSSA.getMemoryAccess(StoreB));
864 EXPECT_EQ(Walker.getClobberingMemoryAccess(LoadC),
865 MSSA.getMemoryAccess(StoreC));
866
867 // exercise block numbering
868 EXPECT_TRUE(MSSA.locallyDominates(MSSA.getMemoryAccess(StoreC),
869 MSSA.getMemoryAccess(StoreB)));
870 EXPECT_TRUE(MSSA.locallyDominates(MSSA.getMemoryAccess(StoreA1),
871 MSSA.getMemoryAccess(StoreA2)));
872 }
873
TEST_F(MemorySSATest,Irreducible)874 TEST_F(MemorySSATest, Irreducible) {
875 // Create the equivalent of
876 // x = something
877 // if (...)
878 // goto second_loop_entry
879 // while (...) {
880 // second_loop_entry:
881 // }
882 // use(x)
883
884 SmallVector<PHINode *, 8> Inserted;
885 IRBuilder<> B(C);
886 F = Function::Create(
887 FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
888 GlobalValue::ExternalLinkage, "F", &M);
889
890 // Make blocks
891 BasicBlock *IfBB = BasicBlock::Create(C, "if", F);
892 BasicBlock *LoopStartBB = BasicBlock::Create(C, "loopstart", F);
893 BasicBlock *LoopMainBB = BasicBlock::Create(C, "loopmain", F);
894 BasicBlock *AfterLoopBB = BasicBlock::Create(C, "afterloop", F);
895 B.SetInsertPoint(IfBB);
896 B.CreateCondBr(B.getTrue(), LoopMainBB, LoopStartBB);
897 B.SetInsertPoint(LoopStartBB);
898 B.CreateBr(LoopMainBB);
899 B.SetInsertPoint(LoopMainBB);
900 B.CreateCondBr(B.getTrue(), LoopStartBB, AfterLoopBB);
901 B.SetInsertPoint(AfterLoopBB);
902 Argument *FirstArg = &*F->arg_begin();
903 setupAnalyses();
904 MemorySSA &MSSA = *Analyses->MSSA;
905 MemorySSAUpdater Updater(&MSSA);
906 // Create the load memory acccess
907 LoadInst *LoadInst = B.CreateLoad(B.getInt8Ty(), FirstArg);
908 MemoryUse *LoadAccess = cast<MemoryUse>(Updater.createMemoryAccessInBB(
909 LoadInst, nullptr, AfterLoopBB, MemorySSA::Beginning));
910 Updater.insertUse(LoadAccess);
911 MSSA.verifyMemorySSA();
912 }
913
TEST_F(MemorySSATest,MoveToBeforeLiveOnEntryInvalidatesCache)914 TEST_F(MemorySSATest, MoveToBeforeLiveOnEntryInvalidatesCache) {
915 // Create:
916 // %1 = alloca i8
917 // ; 1 = MemoryDef(liveOnEntry)
918 // store i8 0, i8* %1
919 // ; 2 = MemoryDef(1)
920 // store i8 0, i8* %1
921 //
922 // ...And be sure that MSSA's caching doesn't give us `1` for the clobber of
923 // `2` after `1` is removed.
924 IRBuilder<> B(C);
925 F = Function::Create(
926 FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
927 GlobalValue::ExternalLinkage, "F", &M);
928
929 BasicBlock *Entry = BasicBlock::Create(C, "if", F);
930 B.SetInsertPoint(Entry);
931
932 Value *A = B.CreateAlloca(B.getInt8Ty());
933 StoreInst *StoreA = B.CreateStore(B.getInt8(0), A);
934 StoreInst *StoreB = B.CreateStore(B.getInt8(0), A);
935
936 setupAnalyses();
937
938 MemorySSA &MSSA = *Analyses->MSSA;
939
940 auto *DefA = cast<MemoryDef>(MSSA.getMemoryAccess(StoreA));
941 auto *DefB = cast<MemoryDef>(MSSA.getMemoryAccess(StoreB));
942
943 MemoryAccess *BClobber = MSSA.getWalker()->getClobberingMemoryAccess(DefB);
944 ASSERT_EQ(DefA, BClobber);
945
946 MemorySSAUpdater(&MSSA).removeMemoryAccess(DefA);
947 StoreA->eraseFromParent();
948
949 EXPECT_EQ(DefB->getDefiningAccess(), MSSA.getLiveOnEntryDef());
950
951 EXPECT_EQ(MSSA.getWalker()->getClobberingMemoryAccess(DefB),
952 MSSA.getLiveOnEntryDef())
953 << "(DefA = " << DefA << ")";
954 }
955
TEST_F(MemorySSATest,RemovingDefInvalidatesCache)956 TEST_F(MemorySSATest, RemovingDefInvalidatesCache) {
957 // Create:
958 // %x = alloca i8
959 // %y = alloca i8
960 // ; 1 = MemoryDef(liveOnEntry)
961 // store i8 0, i8* %x
962 // ; 2 = MemoryDef(1)
963 // store i8 0, i8* %y
964 // ; 3 = MemoryDef(2)
965 // store i8 0, i8* %x
966 //
967 // And be sure that MSSA's caching handles the removal of def `1`
968 // appropriately.
969 IRBuilder<> B(C);
970 F = Function::Create(
971 FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
972 GlobalValue::ExternalLinkage, "F", &M);
973
974 BasicBlock *Entry = BasicBlock::Create(C, "if", F);
975 B.SetInsertPoint(Entry);
976
977 Value *X = B.CreateAlloca(B.getInt8Ty());
978 Value *Y = B.CreateAlloca(B.getInt8Ty());
979 StoreInst *StoreX1 = B.CreateStore(B.getInt8(0), X);
980 StoreInst *StoreY = B.CreateStore(B.getInt8(0), Y);
981 StoreInst *StoreX2 = B.CreateStore(B.getInt8(0), X);
982
983 setupAnalyses();
984
985 MemorySSA &MSSA = *Analyses->MSSA;
986
987 auto *DefX1 = cast<MemoryDef>(MSSA.getMemoryAccess(StoreX1));
988 auto *DefY = cast<MemoryDef>(MSSA.getMemoryAccess(StoreY));
989 auto *DefX2 = cast<MemoryDef>(MSSA.getMemoryAccess(StoreX2));
990
991 EXPECT_EQ(DefX2->getDefiningAccess(), DefY);
992 MemoryAccess *X2Clobber = MSSA.getWalker()->getClobberingMemoryAccess(DefX2);
993 ASSERT_EQ(DefX1, X2Clobber);
994
995 MemorySSAUpdater(&MSSA).removeMemoryAccess(DefX1);
996 StoreX1->eraseFromParent();
997
998 EXPECT_EQ(DefX2->getDefiningAccess(), DefY);
999 EXPECT_EQ(MSSA.getWalker()->getClobberingMemoryAccess(DefX2),
1000 MSSA.getLiveOnEntryDef())
1001 << "(DefX1 = " << DefX1 << ")";
1002 }
1003
1004 // Test Must alias for optimized uses
TEST_F(MemorySSATest,TestLoadMustAlias)1005 TEST_F(MemorySSATest, TestLoadMustAlias) {
1006 F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false),
1007 GlobalValue::ExternalLinkage, "F", &M);
1008 B.SetInsertPoint(BasicBlock::Create(C, "", F));
1009 Type *Int8 = Type::getInt8Ty(C);
1010 Value *AllocaA = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A");
1011 Value *AllocaB = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "B");
1012
1013 B.CreateStore(ConstantInt::get(Int8, 1), AllocaB);
1014 // Check load from LOE
1015 LoadInst *LA1 = B.CreateLoad(Int8, AllocaA, "");
1016 // Check load alias cached for second load
1017 LoadInst *LA2 = B.CreateLoad(Int8, AllocaA, "");
1018
1019 B.CreateStore(ConstantInt::get(Int8, 1), AllocaA);
1020 // Check load from store/def
1021 LoadInst *LA3 = B.CreateLoad(Int8, AllocaA, "");
1022 // Check load alias cached for second load
1023 LoadInst *LA4 = B.CreateLoad(Int8, AllocaA, "");
1024
1025 setupAnalyses();
1026 MemorySSA &MSSA = *Analyses->MSSA;
1027
1028 unsigned I = 0;
1029 for (LoadInst *V : {LA1, LA2}) {
1030 MemoryUse *MemUse = dyn_cast_or_null<MemoryUse>(MSSA.getMemoryAccess(V));
1031 EXPECT_EQ(MemUse->getOptimizedAccessType(), None)
1032 << "Load " << I << " doesn't have the correct alias information";
1033 // EXPECT_EQ expands such that if we increment I above, it won't get
1034 // incremented except when we try to print the error message.
1035 ++I;
1036 }
1037 for (LoadInst *V : {LA3, LA4}) {
1038 MemoryUse *MemUse = dyn_cast_or_null<MemoryUse>(MSSA.getMemoryAccess(V));
1039 EXPECT_EQ(MemUse->getOptimizedAccessType(), MustAlias)
1040 << "Load " << I << " doesn't have the correct alias information";
1041 // EXPECT_EQ expands such that if we increment I above, it won't get
1042 // incremented except when we try to print the error message.
1043 ++I;
1044 }
1045 }
1046
1047 // Test Must alias for optimized defs.
TEST_F(MemorySSATest,TestStoreMustAlias)1048 TEST_F(MemorySSATest, TestStoreMustAlias) {
1049 F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false),
1050 GlobalValue::ExternalLinkage, "F", &M);
1051 B.SetInsertPoint(BasicBlock::Create(C, "", F));
1052 Type *Int8 = Type::getInt8Ty(C);
1053 Value *AllocaA = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A");
1054 Value *AllocaB = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "B");
1055 StoreInst *SA1 = B.CreateStore(ConstantInt::get(Int8, 1), AllocaA);
1056 StoreInst *SB1 = B.CreateStore(ConstantInt::get(Int8, 1), AllocaB);
1057 StoreInst *SA2 = B.CreateStore(ConstantInt::get(Int8, 2), AllocaA);
1058 StoreInst *SB2 = B.CreateStore(ConstantInt::get(Int8, 2), AllocaB);
1059 StoreInst *SA3 = B.CreateStore(ConstantInt::get(Int8, 3), AllocaA);
1060 StoreInst *SB3 = B.CreateStore(ConstantInt::get(Int8, 3), AllocaB);
1061
1062 setupAnalyses();
1063 MemorySSA &MSSA = *Analyses->MSSA;
1064 MemorySSAWalker *Walker = Analyses->Walker;
1065
1066 unsigned I = 0;
1067 for (StoreInst *V : {SA1, SB1, SA2, SB2, SA3, SB3}) {
1068 MemoryDef *MemDef = dyn_cast_or_null<MemoryDef>(MSSA.getMemoryAccess(V));
1069 EXPECT_EQ(MemDef->isOptimized(), false)
1070 << "Store " << I << " is optimized from the start?";
1071 EXPECT_EQ(MemDef->getOptimizedAccessType(), None)
1072 << "Store " << I
1073 << " has correct alias information before being optimized?";
1074 if (V == SA1)
1075 Walker->getClobberingMemoryAccess(V);
1076 else {
1077 MemoryAccess *Def = MemDef->getDefiningAccess();
1078 MemoryAccess *Clob = Walker->getClobberingMemoryAccess(V);
1079 EXPECT_NE(Def, Clob) << "Store " << I
1080 << " has Defining Access equal to Clobbering Access";
1081 }
1082 EXPECT_EQ(MemDef->isOptimized(), true)
1083 << "Store " << I << " was not optimized";
1084 if (I == 0 || I == 1)
1085 EXPECT_EQ(MemDef->getOptimizedAccessType(), None)
1086 << "Store " << I << " doesn't have the correct alias information";
1087 else
1088 EXPECT_EQ(MemDef->getOptimizedAccessType(), MustAlias)
1089 << "Store " << I << " doesn't have the correct alias information";
1090 // EXPECT_EQ expands such that if we increment I above, it won't get
1091 // incremented except when we try to print the error message.
1092 ++I;
1093 }
1094 }
1095
1096 // Test May alias for optimized uses.
TEST_F(MemorySSATest,TestLoadMayAlias)1097 TEST_F(MemorySSATest, TestLoadMayAlias) {
1098 F = Function::Create(FunctionType::get(B.getVoidTy(),
1099 {B.getInt8PtrTy(), B.getInt8PtrTy()},
1100 false),
1101 GlobalValue::ExternalLinkage, "F", &M);
1102 B.SetInsertPoint(BasicBlock::Create(C, "", F));
1103 Type *Int8 = Type::getInt8Ty(C);
1104 auto *ArgIt = F->arg_begin();
1105 Argument *PointerA = &*ArgIt;
1106 Argument *PointerB = &*(++ArgIt);
1107 B.CreateStore(ConstantInt::get(Int8, 1), PointerB);
1108 LoadInst *LA1 = B.CreateLoad(Int8, PointerA, "");
1109 B.CreateStore(ConstantInt::get(Int8, 0), PointerA);
1110 LoadInst *LB1 = B.CreateLoad(Int8, PointerB, "");
1111 B.CreateStore(ConstantInt::get(Int8, 0), PointerA);
1112 LoadInst *LA2 = B.CreateLoad(Int8, PointerA, "");
1113 B.CreateStore(ConstantInt::get(Int8, 0), PointerB);
1114 LoadInst *LB2 = B.CreateLoad(Int8, PointerB, "");
1115
1116 setupAnalyses();
1117 MemorySSA &MSSA = *Analyses->MSSA;
1118
1119 unsigned I = 0;
1120 for (LoadInst *V : {LA1, LB1}) {
1121 MemoryUse *MemUse = dyn_cast_or_null<MemoryUse>(MSSA.getMemoryAccess(V));
1122 EXPECT_EQ(MemUse->getOptimizedAccessType(), MayAlias)
1123 << "Load " << I << " doesn't have the correct alias information";
1124 // EXPECT_EQ expands such that if we increment I above, it won't get
1125 // incremented except when we try to print the error message.
1126 ++I;
1127 }
1128 for (LoadInst *V : {LA2, LB2}) {
1129 MemoryUse *MemUse = dyn_cast_or_null<MemoryUse>(MSSA.getMemoryAccess(V));
1130 EXPECT_EQ(MemUse->getOptimizedAccessType(), MustAlias)
1131 << "Load " << I << " doesn't have the correct alias information";
1132 // EXPECT_EQ expands such that if we increment I above, it won't get
1133 // incremented except when we try to print the error message.
1134 ++I;
1135 }
1136 }
1137
1138 // Test May alias for optimized defs.
TEST_F(MemorySSATest,TestStoreMayAlias)1139 TEST_F(MemorySSATest, TestStoreMayAlias) {
1140 F = Function::Create(FunctionType::get(B.getVoidTy(),
1141 {B.getInt8PtrTy(), B.getInt8PtrTy()},
1142 false),
1143 GlobalValue::ExternalLinkage, "F", &M);
1144 B.SetInsertPoint(BasicBlock::Create(C, "", F));
1145 Type *Int8 = Type::getInt8Ty(C);
1146 auto *ArgIt = F->arg_begin();
1147 Argument *PointerA = &*ArgIt;
1148 Argument *PointerB = &*(++ArgIt);
1149 Value *AllocaC = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "C");
1150 // Store into arg1, must alias because it's LOE => must
1151 StoreInst *SA1 = B.CreateStore(ConstantInt::get(Int8, 0), PointerA);
1152 // Store into arg2, may alias store to arg1 => may
1153 StoreInst *SB1 = B.CreateStore(ConstantInt::get(Int8, 1), PointerB);
1154 // Store into aloca, no alias with args, so must alias LOE => must
1155 StoreInst *SC1 = B.CreateStore(ConstantInt::get(Int8, 2), AllocaC);
1156 // Store into arg1, may alias store to arg2 => may
1157 StoreInst *SA2 = B.CreateStore(ConstantInt::get(Int8, 3), PointerA);
1158 // Store into arg2, may alias store to arg1 => may
1159 StoreInst *SB2 = B.CreateStore(ConstantInt::get(Int8, 4), PointerB);
1160 // Store into aloca, no alias with args, so must alias SC1 => must
1161 StoreInst *SC2 = B.CreateStore(ConstantInt::get(Int8, 5), AllocaC);
1162 // Store into arg2, must alias store to arg2 => must
1163 StoreInst *SB3 = B.CreateStore(ConstantInt::get(Int8, 6), PointerB);
1164 std::initializer_list<StoreInst *> Sts = {SA1, SB1, SC1, SA2, SB2, SC2, SB3};
1165
1166 setupAnalyses();
1167 MemorySSA &MSSA = *Analyses->MSSA;
1168 MemorySSAWalker *Walker = Analyses->Walker;
1169
1170 unsigned I = 0;
1171 for (StoreInst *V : Sts) {
1172 MemoryDef *MemDef = dyn_cast_or_null<MemoryDef>(MSSA.getMemoryAccess(V));
1173 EXPECT_EQ(MemDef->isOptimized(), false)
1174 << "Store " << I << " is optimized from the start?";
1175 EXPECT_EQ(MemDef->getOptimizedAccessType(), None)
1176 << "Store " << I
1177 << " has correct alias information before being optimized?";
1178 ++I;
1179 }
1180
1181 for (StoreInst *V : Sts)
1182 Walker->getClobberingMemoryAccess(V);
1183
1184 I = 0;
1185 for (StoreInst *V : Sts) {
1186 MemoryDef *MemDef = dyn_cast_or_null<MemoryDef>(MSSA.getMemoryAccess(V));
1187 EXPECT_EQ(MemDef->isOptimized(), true)
1188 << "Store " << I << " was not optimized";
1189 if (I == 1 || I == 3 || I == 4)
1190 EXPECT_EQ(MemDef->getOptimizedAccessType(), MayAlias)
1191 << "Store " << I << " doesn't have the correct alias information";
1192 else if (I == 0 || I == 2)
1193 EXPECT_EQ(MemDef->getOptimizedAccessType(), None)
1194 << "Store " << I << " doesn't have the correct alias information";
1195 else
1196 EXPECT_EQ(MemDef->getOptimizedAccessType(), MustAlias)
1197 << "Store " << I << " doesn't have the correct alias information";
1198 // EXPECT_EQ expands such that if we increment I above, it won't get
1199 // incremented except when we try to print the error message.
1200 ++I;
1201 }
1202 }
1203
TEST_F(MemorySSATest,LifetimeMarkersAreClobbers)1204 TEST_F(MemorySSATest, LifetimeMarkersAreClobbers) {
1205 // Example code:
1206 // define void @a(i8* %foo) {
1207 // %bar = getelementptr i8, i8* %foo, i64 1
1208 // %baz = getelementptr i8, i8* %foo, i64 2
1209 // store i8 0, i8* %foo
1210 // store i8 0, i8* %bar
1211 // call void @llvm.lifetime.end.p0i8(i64 3, i8* %foo)
1212 // call void @llvm.lifetime.start.p0i8(i64 3, i8* %foo)
1213 // store i8 0, i8* %foo
1214 // store i8 0, i8* %bar
1215 // call void @llvm.memset.p0i8(i8* %baz, i8 0, i64 1)
1216 // ret void
1217 // }
1218 //
1219 // Patterns like this are possible after inlining; the stores to %foo and %bar
1220 // should both be clobbered by the lifetime.start call if they're dominated by
1221 // it.
1222
1223 IRBuilder<> B(C);
1224 F = Function::Create(
1225 FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
1226 GlobalValue::ExternalLinkage, "F", &M);
1227
1228 // Make blocks
1229 BasicBlock *Entry = BasicBlock::Create(C, "entry", F);
1230
1231 B.SetInsertPoint(Entry);
1232 Value *Foo = &*F->arg_begin();
1233
1234 Value *Bar = B.CreateGEP(B.getInt8Ty(), Foo, B.getInt64(1), "bar");
1235 Value *Baz = B.CreateGEP(B.getInt8Ty(), Foo, B.getInt64(2), "baz");
1236
1237 B.CreateStore(B.getInt8(0), Foo);
1238 B.CreateStore(B.getInt8(0), Bar);
1239
1240 auto GetLifetimeIntrinsic = [&](Intrinsic::ID ID) {
1241 return Intrinsic::getDeclaration(&M, ID, {Foo->getType()});
1242 };
1243
1244 B.CreateCall(GetLifetimeIntrinsic(Intrinsic::lifetime_end),
1245 {B.getInt64(3), Foo});
1246 Instruction *LifetimeStart = B.CreateCall(
1247 GetLifetimeIntrinsic(Intrinsic::lifetime_start), {B.getInt64(3), Foo});
1248
1249 Instruction *FooStore = B.CreateStore(B.getInt8(0), Foo);
1250 Instruction *BarStore = B.CreateStore(B.getInt8(0), Bar);
1251 Instruction *BazMemSet = B.CreateMemSet(Baz, B.getInt8(0), 1, Align(1));
1252
1253 setupAnalyses();
1254 MemorySSA &MSSA = *Analyses->MSSA;
1255
1256 MemoryAccess *LifetimeStartAccess = MSSA.getMemoryAccess(LifetimeStart);
1257 ASSERT_NE(LifetimeStartAccess, nullptr);
1258
1259 MemoryAccess *FooAccess = MSSA.getMemoryAccess(FooStore);
1260 ASSERT_NE(FooAccess, nullptr);
1261
1262 MemoryAccess *BarAccess = MSSA.getMemoryAccess(BarStore);
1263 ASSERT_NE(BarAccess, nullptr);
1264
1265 MemoryAccess *BazAccess = MSSA.getMemoryAccess(BazMemSet);
1266 ASSERT_NE(BazAccess, nullptr);
1267
1268 MemoryAccess *FooClobber =
1269 MSSA.getWalker()->getClobberingMemoryAccess(FooAccess);
1270 EXPECT_EQ(FooClobber, LifetimeStartAccess);
1271
1272 MemoryAccess *BarClobber =
1273 MSSA.getWalker()->getClobberingMemoryAccess(BarAccess);
1274 EXPECT_EQ(BarClobber, LifetimeStartAccess);
1275
1276 MemoryAccess *BazClobber =
1277 MSSA.getWalker()->getClobberingMemoryAccess(BazAccess);
1278 EXPECT_EQ(BazClobber, LifetimeStartAccess);
1279
1280 MemoryAccess *LifetimeStartClobber =
1281 MSSA.getWalker()->getClobberingMemoryAccess(
1282 LifetimeStartAccess, MemoryLocation::getAfter(Foo));
1283 EXPECT_EQ(LifetimeStartClobber, LifetimeStartAccess);
1284 }
1285
TEST_F(MemorySSATest,DefOptimizationsAreInvalidatedOnMoving)1286 TEST_F(MemorySSATest, DefOptimizationsAreInvalidatedOnMoving) {
1287 IRBuilder<> B(C);
1288 F = Function::Create(FunctionType::get(B.getVoidTy(), {B.getInt1Ty()}, false),
1289 GlobalValue::ExternalLinkage, "F", &M);
1290
1291 // Make a CFG like
1292 // entry
1293 // / \
1294 // a b
1295 // \ /
1296 // c
1297 //
1298 // Put a def in A and a def in B, move the def from A -> B, observe as the
1299 // optimization is invalidated.
1300 BasicBlock *Entry = BasicBlock::Create(C, "entry", F);
1301 BasicBlock *BlockA = BasicBlock::Create(C, "a", F);
1302 BasicBlock *BlockB = BasicBlock::Create(C, "b", F);
1303 BasicBlock *BlockC = BasicBlock::Create(C, "c", F);
1304
1305 B.SetInsertPoint(Entry);
1306 Type *Int8 = Type::getInt8Ty(C);
1307 Value *Alloca = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "alloc");
1308 StoreInst *StoreEntry = B.CreateStore(B.getInt8(0), Alloca);
1309 B.CreateCondBr(B.getTrue(), BlockA, BlockB);
1310
1311 B.SetInsertPoint(BlockA);
1312 StoreInst *StoreA = B.CreateStore(B.getInt8(1), Alloca);
1313 B.CreateBr(BlockC);
1314
1315 B.SetInsertPoint(BlockB);
1316 StoreInst *StoreB = B.CreateStore(B.getInt8(2), Alloca);
1317 B.CreateBr(BlockC);
1318
1319 B.SetInsertPoint(BlockC);
1320 B.CreateUnreachable();
1321
1322 setupAnalyses();
1323 MemorySSA &MSSA = *Analyses->MSSA;
1324
1325 auto *AccessEntry = cast<MemoryDef>(MSSA.getMemoryAccess(StoreEntry));
1326 auto *StoreAEntry = cast<MemoryDef>(MSSA.getMemoryAccess(StoreA));
1327 auto *StoreBEntry = cast<MemoryDef>(MSSA.getMemoryAccess(StoreB));
1328
1329 ASSERT_EQ(MSSA.getWalker()->getClobberingMemoryAccess(StoreAEntry),
1330 AccessEntry);
1331 ASSERT_TRUE(StoreAEntry->isOptimized());
1332
1333 ASSERT_EQ(MSSA.getWalker()->getClobberingMemoryAccess(StoreBEntry),
1334 AccessEntry);
1335 ASSERT_TRUE(StoreBEntry->isOptimized());
1336
1337 // Note that if we did InsertionPlace::Beginning, we don't go out of our way
1338 // to invalidate the cache for StoreBEntry. If the user wants to actually do
1339 // moves like these, it's up to them to ensure that nearby cache entries are
1340 // correctly invalidated (which, in general, requires walking all instructions
1341 // that the moved instruction dominates. So we probably shouldn't be doing
1342 // moves like this in general. Still, works as a test-case. ;) )
1343 MemorySSAUpdater(&MSSA).moveToPlace(StoreAEntry, BlockB,
1344 MemorySSA::InsertionPlace::End);
1345 ASSERT_FALSE(StoreAEntry->isOptimized());
1346 ASSERT_EQ(MSSA.getWalker()->getClobberingMemoryAccess(StoreAEntry),
1347 StoreBEntry);
1348 }
1349
TEST_F(MemorySSATest,TestOptimizedDefsAreProperUses)1350 TEST_F(MemorySSATest, TestOptimizedDefsAreProperUses) {
1351 F = Function::Create(FunctionType::get(B.getVoidTy(),
1352 {B.getInt8PtrTy(), B.getInt8PtrTy()},
1353 false),
1354 GlobalValue::ExternalLinkage, "F", &M);
1355 B.SetInsertPoint(BasicBlock::Create(C, "", F));
1356 Type *Int8 = Type::getInt8Ty(C);
1357 Value *AllocA = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A");
1358 Value *AllocB = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "B");
1359
1360 StoreInst *StoreA = B.CreateStore(ConstantInt::get(Int8, 0), AllocA);
1361 StoreInst *StoreB = B.CreateStore(ConstantInt::get(Int8, 1), AllocB);
1362 StoreInst *StoreA2 = B.CreateStore(ConstantInt::get(Int8, 2), AllocA);
1363
1364 setupAnalyses();
1365 MemorySSA &MSSA = *Analyses->MSSA;
1366 MemorySSAWalker *Walker = Analyses->Walker;
1367
1368 // If these don't hold, there's no chance of the test result being useful.
1369 ASSERT_EQ(Walker->getClobberingMemoryAccess(StoreA),
1370 MSSA.getLiveOnEntryDef());
1371 ASSERT_EQ(Walker->getClobberingMemoryAccess(StoreB),
1372 MSSA.getLiveOnEntryDef());
1373 auto *StoreAAccess = cast<MemoryDef>(MSSA.getMemoryAccess(StoreA));
1374 auto *StoreA2Access = cast<MemoryDef>(MSSA.getMemoryAccess(StoreA2));
1375 ASSERT_EQ(Walker->getClobberingMemoryAccess(StoreA2), StoreAAccess);
1376 ASSERT_EQ(StoreA2Access->getOptimized(), StoreAAccess);
1377
1378 auto *StoreBAccess = cast<MemoryDef>(MSSA.getMemoryAccess(StoreB));
1379 ASSERT_LT(StoreAAccess->getID(), StoreBAccess->getID());
1380 ASSERT_LT(StoreBAccess->getID(), StoreA2Access->getID());
1381
1382 auto SortVecByID = [](std::vector<const MemoryDef *> &Defs) {
1383 llvm::sort(Defs, [](const MemoryDef *LHS, const MemoryDef *RHS) {
1384 return LHS->getID() < RHS->getID();
1385 });
1386 };
1387
1388 auto SortedUserList = [&](const MemoryDef *MD) {
1389 std::vector<const MemoryDef *> Result;
1390 transform(MD->users(), std::back_inserter(Result),
1391 [](const User *U) { return cast<MemoryDef>(U); });
1392 SortVecByID(Result);
1393 return Result;
1394 };
1395
1396 // Use std::vectors, since they have nice pretty-printing if the test fails.
1397 // Parens are necessary because EXPECT_EQ is a macro, and we have commas in
1398 // our init lists...
1399 EXPECT_EQ(SortedUserList(StoreAAccess),
1400 (std::vector<const MemoryDef *>{StoreBAccess, StoreA2Access}));
1401
1402 EXPECT_EQ(SortedUserList(StoreBAccess),
1403 std::vector<const MemoryDef *>{StoreA2Access});
1404
1405 // StoreAAccess should be present twice, since it uses liveOnEntry for both
1406 // its defining and optimized accesses. This is a bit awkward, and is not
1407 // relied upon anywhere at the moment. If this is painful, we can fix it.
1408 EXPECT_EQ(SortedUserList(cast<MemoryDef>(MSSA.getLiveOnEntryDef())),
1409 (std::vector<const MemoryDef *>{StoreAAccess, StoreAAccess,
1410 StoreBAccess}));
1411 }
1412
1413 // entry
1414 // |
1415 // header
1416 // / \
1417 // body |
1418 // \ /
1419 // exit
1420 // header:
1421 // ; 1 = MemoryDef(liveOnEntry)
1422 // body:
1423 // ; 2 = MemoryDef(1)
1424 // exit:
1425 // ; 3 = MemoryPhi({body, 2}, {header, 1})
1426 // ; 4 = MemoryDef(3); optimized to 3, cannot optimize thorugh phi.
1427 // Insert edge: entry -> exit, check mssa Update is correct.
TEST_F(MemorySSATest,TestAddedEdgeToBlockWithPhiNotOpt)1428 TEST_F(MemorySSATest, TestAddedEdgeToBlockWithPhiNotOpt) {
1429 F = Function::Create(
1430 FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
1431 GlobalValue::ExternalLinkage, "F", &M);
1432 Argument *PointerArg = &*F->arg_begin();
1433 BasicBlock *Entry(BasicBlock::Create(C, "entry", F));
1434 BasicBlock *Header(BasicBlock::Create(C, "header", F));
1435 BasicBlock *Body(BasicBlock::Create(C, "body", F));
1436 BasicBlock *Exit(BasicBlock::Create(C, "exit", F));
1437 B.SetInsertPoint(Entry);
1438 BranchInst::Create(Header, Entry);
1439 B.SetInsertPoint(Header);
1440 B.CreateStore(B.getInt8(16), PointerArg);
1441 B.CreateCondBr(B.getTrue(), Exit, Body);
1442 B.SetInsertPoint(Body);
1443 B.CreateStore(B.getInt8(16), PointerArg);
1444 BranchInst::Create(Exit, Body);
1445 B.SetInsertPoint(Exit);
1446 StoreInst *S1 = B.CreateStore(B.getInt8(16), PointerArg);
1447
1448 setupAnalyses();
1449 MemorySSA &MSSA = *Analyses->MSSA;
1450 MemorySSAWalker *Walker = Analyses->Walker;
1451 std::unique_ptr<MemorySSAUpdater> MSSAU =
1452 std::make_unique<MemorySSAUpdater>(&MSSA);
1453
1454 MemoryPhi *Phi = MSSA.getMemoryAccess(Exit);
1455 EXPECT_EQ(Phi, Walker->getClobberingMemoryAccess(S1));
1456
1457 // Alter CFG, add edge: entry -> exit
1458 Entry->getTerminator()->eraseFromParent();
1459 B.SetInsertPoint(Entry);
1460 B.CreateCondBr(B.getTrue(), Header, Exit);
1461 SmallVector<CFGUpdate, 1> Updates;
1462 Updates.push_back({cfg::UpdateKind::Insert, Entry, Exit});
1463 Analyses->DT.applyUpdates(Updates);
1464 MSSAU->applyInsertUpdates(Updates, Analyses->DT);
1465 EXPECT_EQ(Phi, Walker->getClobberingMemoryAccess(S1));
1466 }
1467
1468 // entry
1469 // |
1470 // header
1471 // / \
1472 // body |
1473 // \ /
1474 // exit
1475 // header:
1476 // ; 1 = MemoryDef(liveOnEntry)
1477 // body:
1478 // ; 2 = MemoryDef(1)
1479 // exit:
1480 // ; 3 = MemoryPhi({body, 2}, {header, 1})
1481 // ; 4 = MemoryDef(3); optimize this to 1 now, added edge should invalidate
1482 // the optimized access.
1483 // Insert edge: entry -> exit, check mssa Update is correct.
TEST_F(MemorySSATest,TestAddedEdgeToBlockWithPhiOpt)1484 TEST_F(MemorySSATest, TestAddedEdgeToBlockWithPhiOpt) {
1485 F = Function::Create(
1486 FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
1487 GlobalValue::ExternalLinkage, "F", &M);
1488 Argument *PointerArg = &*F->arg_begin();
1489 Type *Int8 = Type::getInt8Ty(C);
1490 BasicBlock *Entry(BasicBlock::Create(C, "entry", F));
1491 BasicBlock *Header(BasicBlock::Create(C, "header", F));
1492 BasicBlock *Body(BasicBlock::Create(C, "body", F));
1493 BasicBlock *Exit(BasicBlock::Create(C, "exit", F));
1494
1495 B.SetInsertPoint(Entry);
1496 Value *Alloca = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A");
1497 BranchInst::Create(Header, Entry);
1498
1499 B.SetInsertPoint(Header);
1500 StoreInst *S1 = B.CreateStore(B.getInt8(16), PointerArg);
1501 B.CreateCondBr(B.getTrue(), Exit, Body);
1502
1503 B.SetInsertPoint(Body);
1504 B.CreateStore(ConstantInt::get(Int8, 0), Alloca);
1505 BranchInst::Create(Exit, Body);
1506
1507 B.SetInsertPoint(Exit);
1508 StoreInst *S2 = B.CreateStore(B.getInt8(16), PointerArg);
1509
1510 setupAnalyses();
1511 MemorySSA &MSSA = *Analyses->MSSA;
1512 MemorySSAWalker *Walker = Analyses->Walker;
1513 std::unique_ptr<MemorySSAUpdater> MSSAU =
1514 std::make_unique<MemorySSAUpdater>(&MSSA);
1515
1516 MemoryDef *DefS1 = cast<MemoryDef>(MSSA.getMemoryAccess(S1));
1517 EXPECT_EQ(DefS1, Walker->getClobberingMemoryAccess(S2));
1518
1519 // Alter CFG, add edge: entry -> exit
1520 Entry->getTerminator()->eraseFromParent();
1521 B.SetInsertPoint(Entry);
1522 B.CreateCondBr(B.getTrue(), Header, Exit);
1523 SmallVector<CFGUpdate, 1> Updates;
1524 Updates.push_back({cfg::UpdateKind::Insert, Entry, Exit});
1525 Analyses->DT.applyUpdates(Updates);
1526 MSSAU->applyInsertUpdates(Updates, Analyses->DT);
1527
1528 MemoryPhi *Phi = MSSA.getMemoryAccess(Exit);
1529 EXPECT_EQ(Phi, Walker->getClobberingMemoryAccess(S2));
1530 }
1531
1532 // entry
1533 // / |
1534 // a |
1535 // / \ |
1536 // b c f
1537 // \ / |
1538 // d |
1539 // \ /
1540 // e
1541 // f:
1542 // ; 1 = MemoryDef(liveOnEntry)
1543 // e:
1544 // ; 2 = MemoryPhi({d, liveOnEntry}, {f, 1})
1545 //
1546 // Insert edge: f -> c, check update is correct.
1547 // After update:
1548 // f:
1549 // ; 1 = MemoryDef(liveOnEntry)
1550 // c:
1551 // ; 3 = MemoryPhi({a, liveOnEntry}, {f, 1})
1552 // d:
1553 // ; 4 = MemoryPhi({b, liveOnEntry}, {c, 3})
1554 // e:
1555 // ; 2 = MemoryPhi({d, 4}, {f, 1})
TEST_F(MemorySSATest,TestAddedEdgeToBlockWithNoPhiAddNewPhis)1556 TEST_F(MemorySSATest, TestAddedEdgeToBlockWithNoPhiAddNewPhis) {
1557 F = Function::Create(
1558 FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
1559 GlobalValue::ExternalLinkage, "F", &M);
1560 Argument *PointerArg = &*F->arg_begin();
1561 BasicBlock *Entry(BasicBlock::Create(C, "entry", F));
1562 BasicBlock *ABlock(BasicBlock::Create(C, "a", F));
1563 BasicBlock *BBlock(BasicBlock::Create(C, "b", F));
1564 BasicBlock *CBlock(BasicBlock::Create(C, "c", F));
1565 BasicBlock *DBlock(BasicBlock::Create(C, "d", F));
1566 BasicBlock *EBlock(BasicBlock::Create(C, "e", F));
1567 BasicBlock *FBlock(BasicBlock::Create(C, "f", F));
1568
1569 B.SetInsertPoint(Entry);
1570 B.CreateCondBr(B.getTrue(), ABlock, FBlock);
1571 B.SetInsertPoint(ABlock);
1572 B.CreateCondBr(B.getTrue(), BBlock, CBlock);
1573 B.SetInsertPoint(BBlock);
1574 BranchInst::Create(DBlock, BBlock);
1575 B.SetInsertPoint(CBlock);
1576 BranchInst::Create(DBlock, CBlock);
1577 B.SetInsertPoint(DBlock);
1578 BranchInst::Create(EBlock, DBlock);
1579 B.SetInsertPoint(FBlock);
1580 B.CreateStore(B.getInt8(16), PointerArg);
1581 BranchInst::Create(EBlock, FBlock);
1582
1583 setupAnalyses();
1584 MemorySSA &MSSA = *Analyses->MSSA;
1585 std::unique_ptr<MemorySSAUpdater> MSSAU =
1586 std::make_unique<MemorySSAUpdater>(&MSSA);
1587
1588 // Alter CFG, add edge: f -> c
1589 FBlock->getTerminator()->eraseFromParent();
1590 B.SetInsertPoint(FBlock);
1591 B.CreateCondBr(B.getTrue(), CBlock, EBlock);
1592 SmallVector<CFGUpdate, 1> Updates;
1593 Updates.push_back({cfg::UpdateKind::Insert, FBlock, CBlock});
1594 Analyses->DT.applyUpdates(Updates);
1595 MSSAU->applyInsertUpdates(Updates, Analyses->DT);
1596
1597 MemoryPhi *MPC = MSSA.getMemoryAccess(CBlock);
1598 EXPECT_NE(MPC, nullptr);
1599 MemoryPhi *MPD = MSSA.getMemoryAccess(DBlock);
1600 EXPECT_NE(MPD, nullptr);
1601 MemoryPhi *MPE = MSSA.getMemoryAccess(EBlock);
1602 EXPECT_EQ(MPD, MPE->getIncomingValueForBlock(DBlock));
1603 }
1604
TEST_F(MemorySSATest,TestCallClobber)1605 TEST_F(MemorySSATest, TestCallClobber) {
1606 F = Function::Create(
1607 FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
1608 GlobalValue::ExternalLinkage, "F", &M);
1609
1610 Value *Pointer1 = &*F->arg_begin();
1611 BasicBlock *Entry(BasicBlock::Create(C, "", F));
1612 B.SetInsertPoint(Entry);
1613 Value *Pointer2 = B.CreateGEP(B.getInt8Ty(), Pointer1, B.getInt64(1));
1614 Instruction *StorePointer1 = B.CreateStore(B.getInt8(0), Pointer1);
1615 Instruction *StorePointer2 = B.CreateStore(B.getInt8(0), Pointer2);
1616 Instruction *MemSet = B.CreateMemSet(Pointer2, B.getInt8(0), 1, Align(1));
1617
1618 setupAnalyses();
1619 MemorySSA &MSSA = *Analyses->MSSA;
1620 MemorySSAWalker *Walker = Analyses->Walker;
1621
1622 MemoryUseOrDef *Store1Access = MSSA.getMemoryAccess(StorePointer1);
1623 MemoryUseOrDef *Store2Access = MSSA.getMemoryAccess(StorePointer2);
1624 MemoryUseOrDef *MemSetAccess = MSSA.getMemoryAccess(MemSet);
1625
1626 MemoryAccess *Pointer1Clobber = Walker->getClobberingMemoryAccess(
1627 MemSetAccess, MemoryLocation(Pointer1, LocationSize::precise(1)));
1628 EXPECT_EQ(Pointer1Clobber, Store1Access);
1629
1630 MemoryAccess *Pointer2Clobber = Walker->getClobberingMemoryAccess(
1631 MemSetAccess, MemoryLocation(Pointer2, LocationSize::precise(1)));
1632 EXPECT_EQ(Pointer2Clobber, MemSetAccess);
1633
1634 MemoryAccess *MemSetClobber = Walker->getClobberingMemoryAccess(MemSetAccess);
1635 EXPECT_EQ(MemSetClobber, Store2Access);
1636 }
1637
TEST_F(MemorySSATest,TestLoadClobber)1638 TEST_F(MemorySSATest, TestLoadClobber) {
1639 F = Function::Create(
1640 FunctionType::get(B.getVoidTy(), {B.getInt8PtrTy()}, false),
1641 GlobalValue::ExternalLinkage, "F", &M);
1642
1643 Value *Pointer1 = &*F->arg_begin();
1644 BasicBlock *Entry(BasicBlock::Create(C, "", F));
1645 B.SetInsertPoint(Entry);
1646 Value *Pointer2 = B.CreateGEP(B.getInt8Ty(), Pointer1, B.getInt64(1));
1647 Instruction *LoadPointer1 =
1648 B.CreateLoad(B.getInt8Ty(), Pointer1, /* Volatile */ true);
1649 Instruction *LoadPointer2 =
1650 B.CreateLoad(B.getInt8Ty(), Pointer2, /* Volatile */ true);
1651
1652 setupAnalyses();
1653 MemorySSA &MSSA = *Analyses->MSSA;
1654 MemorySSAWalker *Walker = Analyses->Walker;
1655
1656 MemoryUseOrDef *Load1Access = MSSA.getMemoryAccess(LoadPointer1);
1657 MemoryUseOrDef *Load2Access = MSSA.getMemoryAccess(LoadPointer2);
1658
1659 // When providing a memory location, we should never return a load as the
1660 // clobber.
1661 MemoryAccess *Pointer1Clobber = Walker->getClobberingMemoryAccess(
1662 Load2Access, MemoryLocation(Pointer1, LocationSize::precise(1)));
1663 EXPECT_TRUE(MSSA.isLiveOnEntryDef(Pointer1Clobber));
1664
1665 MemoryAccess *Pointer2Clobber = Walker->getClobberingMemoryAccess(
1666 Load2Access, MemoryLocation(Pointer2, LocationSize::precise(1)));
1667 EXPECT_TRUE(MSSA.isLiveOnEntryDef(Pointer2Clobber));
1668
1669 MemoryAccess *Load2Clobber = Walker->getClobberingMemoryAccess(Load2Access);
1670 EXPECT_EQ(Load2Clobber, Load1Access);
1671 }
1672