1 //===- MemorySSA.cpp - Unit tests for MemorySSA ---------------------------===//
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
7 //===----------------------------------------------------------------------===//
8 #include "llvm/Analysis/MemorySSA.h"
9 #include "llvm/Analysis/AliasAnalysis.h"
10 #include "llvm/Analysis/BasicAliasAnalysis.h"
11 #include "llvm/Analysis/MemorySSAUpdater.h"
12 #include "llvm/IR/BasicBlock.h"
13 #include "llvm/IR/DataLayout.h"
14 #include "llvm/IR/Dominators.h"
15 #include "llvm/IR/IRBuilder.h"
16 #include "llvm/IR/Instructions.h"
17 #include "llvm/IR/LLVMContext.h"
18 #include "gtest/gtest.h"
22 const static char DLString
[] = "e-i64:64-f80:128-n8:16:32:64-S128";
24 /// There's a lot of common setup between these tests. This fixture helps reduce
25 /// that. Tests should mock up a function, store it in F, and then call
27 class MemorySSATest
: public testing::Test
{
29 // N.B. Many of these members depend on each other (e.g. the Module depends on
30 // the Context, etc.). So, order matters here (and in TestAnalyses).
35 TargetLibraryInfoImpl TLII
;
36 TargetLibraryInfo TLI
;
39 // Things that we need to build after the function is created.
45 // We need to defer MSSA construction until AA is *entirely* set up, which
46 // requires calling addAAResult. Hence, we just use a pointer here.
47 std::unique_ptr
<MemorySSA
> MSSA
;
48 MemorySSAWalker
*Walker
;
50 TestAnalyses(MemorySSATest
&Test
)
51 : DT(*Test
.F
), AC(*Test
.F
), AA(Test
.TLI
),
52 BAA(Test
.DL
, *Test
.F
, Test
.TLI
, AC
, &DT
) {
54 MSSA
= std::make_unique
<MemorySSA
>(*Test
.F
, &AA
, &DT
);
55 Walker
= MSSA
->getWalker();
59 std::unique_ptr
<TestAnalyses
> Analyses
;
61 void setupAnalyses() {
63 Analyses
.reset(new TestAnalyses(*this));
68 : M("MemorySSATest", C
), B(C
), DL(DLString
), TLI(TLII
), F(nullptr) {}
71 TEST_F(MemorySSATest
, CreateALoad
) {
72 // We create a diamond where there is a store on one side, and then after
73 // building MemorySSA, create a load after the merge point, and use it to test
74 // updating by creating an access for the load.
76 FunctionType::get(B
.getVoidTy(), {B
.getInt8PtrTy()}, false),
77 GlobalValue::ExternalLinkage
, "F", &M
);
78 BasicBlock
*Entry(BasicBlock::Create(C
, "", F
));
79 BasicBlock
*Left(BasicBlock::Create(C
, "", F
));
80 BasicBlock
*Right(BasicBlock::Create(C
, "", F
));
81 BasicBlock
*Merge(BasicBlock::Create(C
, "", F
));
82 B
.SetInsertPoint(Entry
);
83 B
.CreateCondBr(B
.getTrue(), Left
, Right
);
84 B
.SetInsertPoint(Left
);
85 Argument
*PointerArg
= &*F
->arg_begin();
86 B
.CreateStore(B
.getInt8(16), PointerArg
);
87 BranchInst::Create(Merge
, Left
);
88 BranchInst::Create(Merge
, Right
);
91 MemorySSA
&MSSA
= *Analyses
->MSSA
;
92 MemorySSAUpdater
Updater(&MSSA
);
94 B
.SetInsertPoint(Merge
);
95 LoadInst
*LoadInst
= B
.CreateLoad(B
.getInt8Ty(), PointerArg
);
97 // MemoryPHI should already exist.
98 MemoryPhi
*MP
= MSSA
.getMemoryAccess(Merge
);
99 EXPECT_NE(MP
, nullptr);
101 // Create the load memory acccess
102 MemoryUse
*LoadAccess
= cast
<MemoryUse
>(Updater
.createMemoryAccessInBB(
103 LoadInst
, MP
, Merge
, MemorySSA::Beginning
));
104 MemoryAccess
*DefiningAccess
= LoadAccess
->getDefiningAccess();
105 EXPECT_TRUE(isa
<MemoryPhi
>(DefiningAccess
));
106 MSSA
.verifyMemorySSA();
108 TEST_F(MemorySSATest
, CreateLoadsAndStoreUpdater
) {
109 // We create a diamond, then build memoryssa with no memory accesses, and
110 // incrementally update it by inserting a store in the, entry, a load in the
111 // merge point, then a store in the branch, another load in the merge point,
112 // and then a store in the entry.
113 F
= Function::Create(
114 FunctionType::get(B
.getVoidTy(), {B
.getInt8PtrTy()}, false),
115 GlobalValue::ExternalLinkage
, "F", &M
);
116 BasicBlock
*Entry(BasicBlock::Create(C
, "", F
));
117 BasicBlock
*Left(BasicBlock::Create(C
, "", F
));
118 BasicBlock
*Right(BasicBlock::Create(C
, "", F
));
119 BasicBlock
*Merge(BasicBlock::Create(C
, "", F
));
120 B
.SetInsertPoint(Entry
);
121 B
.CreateCondBr(B
.getTrue(), Left
, Right
);
122 B
.SetInsertPoint(Left
, Left
->begin());
123 Argument
*PointerArg
= &*F
->arg_begin();
124 B
.SetInsertPoint(Left
);
126 B
.SetInsertPoint(Right
);
130 MemorySSA
&MSSA
= *Analyses
->MSSA
;
131 MemorySSAUpdater
Updater(&MSSA
);
133 B
.SetInsertPoint(Entry
, Entry
->begin());
134 StoreInst
*EntryStore
= B
.CreateStore(B
.getInt8(16), PointerArg
);
135 MemoryAccess
*EntryStoreAccess
= Updater
.createMemoryAccessInBB(
136 EntryStore
, nullptr, Entry
, MemorySSA::Beginning
);
137 Updater
.insertDef(cast
<MemoryDef
>(EntryStoreAccess
));
140 B
.SetInsertPoint(Merge
, Merge
->begin());
141 LoadInst
*FirstLoad
= B
.CreateLoad(B
.getInt8Ty(), PointerArg
);
143 // MemoryPHI should not already exist.
144 MemoryPhi
*MP
= MSSA
.getMemoryAccess(Merge
);
145 EXPECT_EQ(MP
, nullptr);
147 // Create the load memory access
148 MemoryUse
*FirstLoadAccess
= cast
<MemoryUse
>(Updater
.createMemoryAccessInBB(
149 FirstLoad
, nullptr, Merge
, MemorySSA::Beginning
));
150 Updater
.insertUse(FirstLoadAccess
);
151 // Should just have a load using the entry access, because it should discover
152 // the phi is trivial
153 EXPECT_EQ(FirstLoadAccess
->getDefiningAccess(), EntryStoreAccess
);
155 // Create a store on the left
157 B
.SetInsertPoint(Left
, Left
->begin());
158 StoreInst
*LeftStore
= B
.CreateStore(B
.getInt8(16), PointerArg
);
159 MemoryAccess
*LeftStoreAccess
= Updater
.createMemoryAccessInBB(
160 LeftStore
, nullptr, Left
, MemorySSA::Beginning
);
161 Updater
.insertDef(cast
<MemoryDef
>(LeftStoreAccess
), false);
163 // MemoryPHI should exist after adding LeftStore.
164 MP
= MSSA
.getMemoryAccess(Merge
);
165 EXPECT_NE(MP
, nullptr);
167 // Add the second load
168 B
.SetInsertPoint(Merge
, Merge
->begin());
169 LoadInst
*SecondLoad
= B
.CreateLoad(B
.getInt8Ty(), PointerArg
);
171 // Create the load memory access
172 MemoryUse
*SecondLoadAccess
= cast
<MemoryUse
>(Updater
.createMemoryAccessInBB(
173 SecondLoad
, nullptr, Merge
, MemorySSA::Beginning
));
174 Updater
.insertUse(SecondLoadAccess
);
175 // Now the load should be a phi of the entry store and the left store
176 MemoryPhi
*MergePhi
=
177 dyn_cast
<MemoryPhi
>(SecondLoadAccess
->getDefiningAccess());
178 EXPECT_NE(MergePhi
, nullptr);
179 EXPECT_EQ(MergePhi
->getIncomingValue(0), EntryStoreAccess
);
180 EXPECT_EQ(MergePhi
->getIncomingValue(1), LeftStoreAccess
);
181 // Now create a store below the existing one in the entry
182 B
.SetInsertPoint(Entry
, --Entry
->end());
183 StoreInst
*SecondEntryStore
= B
.CreateStore(B
.getInt8(16), PointerArg
);
184 MemoryAccess
*SecondEntryStoreAccess
= Updater
.createMemoryAccessInBB(
185 SecondEntryStore
, nullptr, Entry
, MemorySSA::End
);
186 // Insert it twice just to test renaming
187 Updater
.insertDef(cast
<MemoryDef
>(SecondEntryStoreAccess
), false);
188 EXPECT_NE(FirstLoadAccess
->getDefiningAccess(), MergePhi
);
189 Updater
.insertDef(cast
<MemoryDef
>(SecondEntryStoreAccess
), true);
190 EXPECT_EQ(FirstLoadAccess
->getDefiningAccess(), MergePhi
);
191 // and make sure the phi below it got updated, despite being blocks away
192 MergePhi
= dyn_cast
<MemoryPhi
>(SecondLoadAccess
->getDefiningAccess());
193 EXPECT_NE(MergePhi
, nullptr);
194 EXPECT_EQ(MergePhi
->getIncomingValue(0), SecondEntryStoreAccess
);
195 EXPECT_EQ(MergePhi
->getIncomingValue(1), LeftStoreAccess
);
196 MSSA
.verifyMemorySSA();
199 TEST_F(MemorySSATest
, CreateALoadUpdater
) {
200 // We create a diamond, then build memoryssa with no memory accesses, and
201 // incrementally update it by inserting a store in one of the branches, and a
202 // load in the merge point
203 F
= Function::Create(
204 FunctionType::get(B
.getVoidTy(), {B
.getInt8PtrTy()}, false),
205 GlobalValue::ExternalLinkage
, "F", &M
);
206 BasicBlock
*Entry(BasicBlock::Create(C
, "", F
));
207 BasicBlock
*Left(BasicBlock::Create(C
, "", F
));
208 BasicBlock
*Right(BasicBlock::Create(C
, "", F
));
209 BasicBlock
*Merge(BasicBlock::Create(C
, "", F
));
210 B
.SetInsertPoint(Entry
);
211 B
.CreateCondBr(B
.getTrue(), Left
, Right
);
212 B
.SetInsertPoint(Left
, Left
->begin());
213 Argument
*PointerArg
= &*F
->arg_begin();
214 B
.SetInsertPoint(Left
);
216 B
.SetInsertPoint(Right
);
220 MemorySSA
&MSSA
= *Analyses
->MSSA
;
221 MemorySSAUpdater
Updater(&MSSA
);
222 B
.SetInsertPoint(Left
, Left
->begin());
224 StoreInst
*SI
= B
.CreateStore(B
.getInt8(16), PointerArg
);
225 MemoryAccess
*StoreAccess
=
226 Updater
.createMemoryAccessInBB(SI
, nullptr, Left
, MemorySSA::Beginning
);
227 Updater
.insertDef(cast
<MemoryDef
>(StoreAccess
));
229 // MemoryPHI should be created when inserting the def
230 MemoryPhi
*MP
= MSSA
.getMemoryAccess(Merge
);
231 EXPECT_NE(MP
, nullptr);
234 B
.SetInsertPoint(Merge
, Merge
->begin());
235 LoadInst
*LoadInst
= B
.CreateLoad(B
.getInt8Ty(), PointerArg
);
237 // Create the load memory acccess
238 MemoryUse
*LoadAccess
= cast
<MemoryUse
>(Updater
.createMemoryAccessInBB(
239 LoadInst
, nullptr, Merge
, MemorySSA::Beginning
));
240 Updater
.insertUse(LoadAccess
);
241 MemoryAccess
*DefiningAccess
= LoadAccess
->getDefiningAccess();
242 EXPECT_TRUE(isa
<MemoryPhi
>(DefiningAccess
));
243 MSSA
.verifyMemorySSA();
246 TEST_F(MemorySSATest
, SinkLoad
) {
247 F
= Function::Create(
248 FunctionType::get(B
.getVoidTy(), {B
.getInt8PtrTy()}, false),
249 GlobalValue::ExternalLinkage
, "F", &M
);
250 BasicBlock
*Entry(BasicBlock::Create(C
, "", F
));
251 BasicBlock
*Left(BasicBlock::Create(C
, "", F
));
252 BasicBlock
*Right(BasicBlock::Create(C
, "", F
));
253 BasicBlock
*Merge(BasicBlock::Create(C
, "", F
));
254 B
.SetInsertPoint(Entry
);
255 B
.CreateCondBr(B
.getTrue(), Left
, Right
);
256 B
.SetInsertPoint(Left
, Left
->begin());
257 Argument
*PointerArg
= &*F
->arg_begin();
258 B
.SetInsertPoint(Left
);
260 B
.SetInsertPoint(Right
);
263 // Load in left block
264 B
.SetInsertPoint(Left
, Left
->begin());
265 LoadInst
*LoadInst1
= B
.CreateLoad(B
.getInt8Ty(), PointerArg
);
266 // Store in merge block
267 B
.SetInsertPoint(Merge
, Merge
->begin());
268 B
.CreateStore(B
.getInt8(16), PointerArg
);
271 MemorySSA
&MSSA
= *Analyses
->MSSA
;
272 MemorySSAUpdater
Updater(&MSSA
);
274 // Mimic sinking of a load:
276 // - insert in "exit" block
278 // - remove from original block
280 LoadInst
*LoadInstClone
= cast
<LoadInst
>(LoadInst1
->clone());
281 Merge
->getInstList().insert(Merge
->begin(), LoadInstClone
);
282 MemoryAccess
* NewLoadAccess
=
283 Updater
.createMemoryAccessInBB(LoadInstClone
, nullptr,
284 LoadInstClone
->getParent(),
285 MemorySSA::Beginning
);
286 Updater
.insertUse(cast
<MemoryUse
>(NewLoadAccess
));
287 MSSA
.verifyMemorySSA();
288 Updater
.removeMemoryAccess(MSSA
.getMemoryAccess(LoadInst1
));
289 MSSA
.verifyMemorySSA();
292 TEST_F(MemorySSATest
, MoveAStore
) {
293 // We create a diamond where there is a in the entry, a store on one side, and
294 // a load at the end. After building MemorySSA, we test updating by moving
295 // the store from the side block to the entry block. This destroys the old
297 F
= Function::Create(
298 FunctionType::get(B
.getVoidTy(), {B
.getInt8PtrTy()}, false),
299 GlobalValue::ExternalLinkage
, "F", &M
);
300 BasicBlock
*Entry(BasicBlock::Create(C
, "", F
));
301 BasicBlock
*Left(BasicBlock::Create(C
, "", F
));
302 BasicBlock
*Right(BasicBlock::Create(C
, "", F
));
303 BasicBlock
*Merge(BasicBlock::Create(C
, "", F
));
304 B
.SetInsertPoint(Entry
);
305 Argument
*PointerArg
= &*F
->arg_begin();
306 StoreInst
*EntryStore
= B
.CreateStore(B
.getInt8(16), PointerArg
);
307 B
.CreateCondBr(B
.getTrue(), Left
, Right
);
308 B
.SetInsertPoint(Left
);
309 StoreInst
*SideStore
= B
.CreateStore(B
.getInt8(16), PointerArg
);
310 BranchInst::Create(Merge
, Left
);
311 BranchInst::Create(Merge
, Right
);
312 B
.SetInsertPoint(Merge
);
313 B
.CreateLoad(B
.getInt8Ty(), PointerArg
);
315 MemorySSA
&MSSA
= *Analyses
->MSSA
;
316 MemorySSAUpdater
Updater(&MSSA
);
318 SideStore
->moveBefore(Entry
->getTerminator());
319 MemoryAccess
*EntryStoreAccess
= MSSA
.getMemoryAccess(EntryStore
);
320 MemoryAccess
*SideStoreAccess
= MSSA
.getMemoryAccess(SideStore
);
321 MemoryAccess
*NewStoreAccess
= Updater
.createMemoryAccessAfter(
322 SideStore
, EntryStoreAccess
, EntryStoreAccess
);
323 EntryStoreAccess
->replaceAllUsesWith(NewStoreAccess
);
324 Updater
.removeMemoryAccess(SideStoreAccess
);
325 MSSA
.verifyMemorySSA();
328 TEST_F(MemorySSATest
, MoveAStoreUpdater
) {
329 // We create a diamond where there is a in the entry, a store on one side, and
330 // a load at the end. After building MemorySSA, we test updating by moving
331 // the store from the side block to the entry block. This destroys the old
333 F
= Function::Create(
334 FunctionType::get(B
.getVoidTy(), {B
.getInt8PtrTy()}, false),
335 GlobalValue::ExternalLinkage
, "F", &M
);
336 BasicBlock
*Entry(BasicBlock::Create(C
, "", F
));
337 BasicBlock
*Left(BasicBlock::Create(C
, "", F
));
338 BasicBlock
*Right(BasicBlock::Create(C
, "", F
));
339 BasicBlock
*Merge(BasicBlock::Create(C
, "", F
));
340 B
.SetInsertPoint(Entry
);
341 Argument
*PointerArg
= &*F
->arg_begin();
342 StoreInst
*EntryStore
= B
.CreateStore(B
.getInt8(16), PointerArg
);
343 B
.CreateCondBr(B
.getTrue(), Left
, Right
);
344 B
.SetInsertPoint(Left
);
345 auto *SideStore
= B
.CreateStore(B
.getInt8(16), PointerArg
);
346 BranchInst::Create(Merge
, Left
);
347 BranchInst::Create(Merge
, Right
);
348 B
.SetInsertPoint(Merge
);
349 auto *MergeLoad
= B
.CreateLoad(B
.getInt8Ty(), PointerArg
);
351 MemorySSA
&MSSA
= *Analyses
->MSSA
;
352 MemorySSAUpdater
Updater(&MSSA
);
355 SideStore
->moveBefore(Entry
->getTerminator());
356 auto *EntryStoreAccess
= MSSA
.getMemoryAccess(EntryStore
);
357 auto *SideStoreAccess
= MSSA
.getMemoryAccess(SideStore
);
358 auto *NewStoreAccess
= Updater
.createMemoryAccessAfter(
359 SideStore
, EntryStoreAccess
, EntryStoreAccess
);
360 // Before, the load will point to a phi of the EntryStore and SideStore.
361 auto *LoadAccess
= cast
<MemoryUse
>(MSSA
.getMemoryAccess(MergeLoad
));
362 EXPECT_TRUE(isa
<MemoryPhi
>(LoadAccess
->getDefiningAccess()));
363 MemoryPhi
*MergePhi
= cast
<MemoryPhi
>(LoadAccess
->getDefiningAccess());
364 EXPECT_EQ(MergePhi
->getIncomingValue(1), EntryStoreAccess
);
365 EXPECT_EQ(MergePhi
->getIncomingValue(0), SideStoreAccess
);
366 Updater
.removeMemoryAccess(SideStoreAccess
);
367 Updater
.insertDef(cast
<MemoryDef
>(NewStoreAccess
));
368 // After it's a phi of the new side store access.
369 EXPECT_EQ(MergePhi
->getIncomingValue(0), NewStoreAccess
);
370 EXPECT_EQ(MergePhi
->getIncomingValue(1), NewStoreAccess
);
371 MSSA
.verifyMemorySSA();
374 TEST_F(MemorySSATest
, MoveAStoreUpdaterMove
) {
375 // We create a diamond where there is a in the entry, a store on one side, and
376 // a load at the end. After building MemorySSA, we test updating by moving
377 // the store from the side block to the entry block. This does not destroy
379 F
= Function::Create(
380 FunctionType::get(B
.getVoidTy(), {B
.getInt8PtrTy()}, false),
381 GlobalValue::ExternalLinkage
, "F", &M
);
382 BasicBlock
*Entry(BasicBlock::Create(C
, "", F
));
383 BasicBlock
*Left(BasicBlock::Create(C
, "", F
));
384 BasicBlock
*Right(BasicBlock::Create(C
, "", F
));
385 BasicBlock
*Merge(BasicBlock::Create(C
, "", F
));
386 B
.SetInsertPoint(Entry
);
387 Argument
*PointerArg
= &*F
->arg_begin();
388 StoreInst
*EntryStore
= B
.CreateStore(B
.getInt8(16), PointerArg
);
389 B
.CreateCondBr(B
.getTrue(), Left
, Right
);
390 B
.SetInsertPoint(Left
);
391 auto *SideStore
= B
.CreateStore(B
.getInt8(16), PointerArg
);
392 BranchInst::Create(Merge
, Left
);
393 BranchInst::Create(Merge
, Right
);
394 B
.SetInsertPoint(Merge
);
395 auto *MergeLoad
= B
.CreateLoad(B
.getInt8Ty(), PointerArg
);
397 MemorySSA
&MSSA
= *Analyses
->MSSA
;
398 MemorySSAUpdater
Updater(&MSSA
);
401 auto *EntryStoreAccess
= MSSA
.getMemoryAccess(EntryStore
);
402 auto *SideStoreAccess
= MSSA
.getMemoryAccess(SideStore
);
403 // Before, the load will point to a phi of the EntryStore and SideStore.
404 auto *LoadAccess
= cast
<MemoryUse
>(MSSA
.getMemoryAccess(MergeLoad
));
405 EXPECT_TRUE(isa
<MemoryPhi
>(LoadAccess
->getDefiningAccess()));
406 MemoryPhi
*MergePhi
= cast
<MemoryPhi
>(LoadAccess
->getDefiningAccess());
407 EXPECT_EQ(MergePhi
->getIncomingValue(1), EntryStoreAccess
);
408 EXPECT_EQ(MergePhi
->getIncomingValue(0), SideStoreAccess
);
409 SideStore
->moveBefore(*EntryStore
->getParent(), ++EntryStore
->getIterator());
410 Updater
.moveAfter(SideStoreAccess
, EntryStoreAccess
);
411 // After, it's a phi of the side store.
412 EXPECT_EQ(MergePhi
->getIncomingValue(0), SideStoreAccess
);
413 EXPECT_EQ(MergePhi
->getIncomingValue(1), SideStoreAccess
);
415 MSSA
.verifyMemorySSA();
418 TEST_F(MemorySSATest
, MoveAStoreAllAround
) {
419 // We create a diamond where there is a in the entry, a store on one side, and
420 // a load at the end. After building MemorySSA, we test updating by moving
421 // the store from the side block to the entry block, then to the other side
422 // block, then to before the load. This does not destroy the old access.
423 F
= Function::Create(
424 FunctionType::get(B
.getVoidTy(), {B
.getInt8PtrTy()}, false),
425 GlobalValue::ExternalLinkage
, "F", &M
);
426 BasicBlock
*Entry(BasicBlock::Create(C
, "", F
));
427 BasicBlock
*Left(BasicBlock::Create(C
, "", F
));
428 BasicBlock
*Right(BasicBlock::Create(C
, "", F
));
429 BasicBlock
*Merge(BasicBlock::Create(C
, "", F
));
430 B
.SetInsertPoint(Entry
);
431 Argument
*PointerArg
= &*F
->arg_begin();
432 StoreInst
*EntryStore
= B
.CreateStore(B
.getInt8(16), PointerArg
);
433 B
.CreateCondBr(B
.getTrue(), Left
, Right
);
434 B
.SetInsertPoint(Left
);
435 auto *SideStore
= B
.CreateStore(B
.getInt8(16), PointerArg
);
436 BranchInst::Create(Merge
, Left
);
437 BranchInst::Create(Merge
, Right
);
438 B
.SetInsertPoint(Merge
);
439 auto *MergeLoad
= B
.CreateLoad(B
.getInt8Ty(), PointerArg
);
441 MemorySSA
&MSSA
= *Analyses
->MSSA
;
442 MemorySSAUpdater
Updater(&MSSA
);
445 auto *EntryStoreAccess
= MSSA
.getMemoryAccess(EntryStore
);
446 auto *SideStoreAccess
= MSSA
.getMemoryAccess(SideStore
);
447 // Before, the load will point to a phi of the EntryStore and SideStore.
448 auto *LoadAccess
= cast
<MemoryUse
>(MSSA
.getMemoryAccess(MergeLoad
));
449 EXPECT_TRUE(isa
<MemoryPhi
>(LoadAccess
->getDefiningAccess()));
450 MemoryPhi
*MergePhi
= cast
<MemoryPhi
>(LoadAccess
->getDefiningAccess());
451 EXPECT_EQ(MergePhi
->getIncomingValue(1), EntryStoreAccess
);
452 EXPECT_EQ(MergePhi
->getIncomingValue(0), SideStoreAccess
);
453 // Move the store before the entry store
454 SideStore
->moveBefore(*EntryStore
->getParent(), EntryStore
->getIterator());
455 Updater
.moveBefore(SideStoreAccess
, EntryStoreAccess
);
456 // After, it's a phi of the entry store.
457 EXPECT_EQ(MergePhi
->getIncomingValue(0), EntryStoreAccess
);
458 EXPECT_EQ(MergePhi
->getIncomingValue(1), EntryStoreAccess
);
459 MSSA
.verifyMemorySSA();
460 // Now move the store to the right branch
461 SideStore
->moveBefore(*Right
, Right
->begin());
462 Updater
.moveToPlace(SideStoreAccess
, Right
, MemorySSA::Beginning
);
463 MSSA
.verifyMemorySSA();
464 EXPECT_EQ(MergePhi
->getIncomingValue(0), EntryStoreAccess
);
465 EXPECT_EQ(MergePhi
->getIncomingValue(1), SideStoreAccess
);
466 // Now move it before the load
467 SideStore
->moveBefore(MergeLoad
);
468 Updater
.moveBefore(SideStoreAccess
, LoadAccess
);
469 EXPECT_EQ(MergePhi
->getIncomingValue(0), EntryStoreAccess
);
470 EXPECT_EQ(MergePhi
->getIncomingValue(1), EntryStoreAccess
);
471 MSSA
.verifyMemorySSA();
474 TEST_F(MemorySSATest
, RemoveAPhi
) {
475 // We create a diamond where there is a store on one side, and then a load
476 // after the merge point. This enables us to test a bunch of different
478 F
= Function::Create(
479 FunctionType::get(B
.getVoidTy(), {B
.getInt8PtrTy()}, false),
480 GlobalValue::ExternalLinkage
, "F", &M
);
481 BasicBlock
*Entry(BasicBlock::Create(C
, "", F
));
482 BasicBlock
*Left(BasicBlock::Create(C
, "", F
));
483 BasicBlock
*Right(BasicBlock::Create(C
, "", F
));
484 BasicBlock
*Merge(BasicBlock::Create(C
, "", F
));
485 B
.SetInsertPoint(Entry
);
486 B
.CreateCondBr(B
.getTrue(), Left
, Right
);
487 B
.SetInsertPoint(Left
);
488 Argument
*PointerArg
= &*F
->arg_begin();
489 StoreInst
*StoreInst
= B
.CreateStore(B
.getInt8(16), PointerArg
);
490 BranchInst::Create(Merge
, Left
);
491 BranchInst::Create(Merge
, Right
);
492 B
.SetInsertPoint(Merge
);
493 LoadInst
*LoadInst
= B
.CreateLoad(B
.getInt8Ty(), PointerArg
);
496 MemorySSA
&MSSA
= *Analyses
->MSSA
;
497 MemorySSAUpdater
Updater(&MSSA
);
499 // Before, the load will be a use of a phi<store, liveonentry>.
500 MemoryUse
*LoadAccess
= cast
<MemoryUse
>(MSSA
.getMemoryAccess(LoadInst
));
501 MemoryDef
*StoreAccess
= cast
<MemoryDef
>(MSSA
.getMemoryAccess(StoreInst
));
502 MemoryAccess
*DefiningAccess
= LoadAccess
->getDefiningAccess();
503 EXPECT_TRUE(isa
<MemoryPhi
>(DefiningAccess
));
505 Updater
.removeMemoryAccess(StoreAccess
);
506 MemoryPhi
*MP
= cast
<MemoryPhi
>(DefiningAccess
);
507 // Verify the phi ended up as liveonentry, liveonentry
508 for (auto &Op
: MP
->incoming_values())
509 EXPECT_TRUE(MSSA
.isLiveOnEntryDef(cast
<MemoryAccess
>(Op
.get())));
510 // Replace the phi uses with the live on entry def
511 MP
->replaceAllUsesWith(MSSA
.getLiveOnEntryDef());
512 // Verify the load is now defined by liveOnEntryDef
513 EXPECT_TRUE(MSSA
.isLiveOnEntryDef(LoadAccess
->getDefiningAccess()));
515 Updater
.removeMemoryAccess(MP
);
516 MSSA
.verifyMemorySSA();
519 TEST_F(MemorySSATest
, RemoveMemoryAccess
) {
520 // We create a diamond where there is a store on one side, and then a load
521 // after the merge point. This enables us to test a bunch of different
523 F
= Function::Create(
524 FunctionType::get(B
.getVoidTy(), {B
.getInt8PtrTy()}, false),
525 GlobalValue::ExternalLinkage
, "F", &M
);
526 BasicBlock
*Entry(BasicBlock::Create(C
, "", F
));
527 BasicBlock
*Left(BasicBlock::Create(C
, "", F
));
528 BasicBlock
*Right(BasicBlock::Create(C
, "", F
));
529 BasicBlock
*Merge(BasicBlock::Create(C
, "", F
));
530 B
.SetInsertPoint(Entry
);
531 B
.CreateCondBr(B
.getTrue(), Left
, Right
);
532 B
.SetInsertPoint(Left
);
533 Argument
*PointerArg
= &*F
->arg_begin();
534 StoreInst
*StoreInst
= B
.CreateStore(B
.getInt8(16), PointerArg
);
535 BranchInst::Create(Merge
, Left
);
536 BranchInst::Create(Merge
, Right
);
537 B
.SetInsertPoint(Merge
);
538 LoadInst
*LoadInst
= B
.CreateLoad(B
.getInt8Ty(), PointerArg
);
541 MemorySSA
&MSSA
= *Analyses
->MSSA
;
542 MemorySSAWalker
*Walker
= Analyses
->Walker
;
543 MemorySSAUpdater
Updater(&MSSA
);
545 // Before, the load will be a use of a phi<store, liveonentry>. It should be
547 MemoryUse
*LoadAccess
= cast
<MemoryUse
>(MSSA
.getMemoryAccess(LoadInst
));
548 MemoryDef
*StoreAccess
= cast
<MemoryDef
>(MSSA
.getMemoryAccess(StoreInst
));
549 MemoryAccess
*DefiningAccess
= LoadAccess
->getDefiningAccess();
550 EXPECT_TRUE(isa
<MemoryPhi
>(DefiningAccess
));
551 // The load is currently clobbered by one of the phi arguments, so the walker
552 // should determine the clobbering access as the phi.
553 EXPECT_EQ(DefiningAccess
, Walker
->getClobberingMemoryAccess(LoadInst
));
554 Updater
.removeMemoryAccess(StoreAccess
);
555 MSSA
.verifyMemorySSA();
556 // After the removeaccess, let's see if we got the right accesses
557 // The load should still point to the phi ...
558 EXPECT_EQ(DefiningAccess
, LoadAccess
->getDefiningAccess());
559 // but we should now get live on entry for the clobbering definition of the
560 // load, since it will walk past the phi node since every argument is the
562 // XXX: This currently requires either removing the phi or resetting optimized
566 MSSA
.isLiveOnEntryDef(Walker
->getClobberingMemoryAccess(LoadInst
)));
567 // If we reset optimized, we get live on entry.
568 LoadAccess
->resetOptimized();
570 MSSA
.isLiveOnEntryDef(Walker
->getClobberingMemoryAccess(LoadInst
)));
571 // The phi should now be a two entry phi with two live on entry defs.
572 for (const auto &Op
: DefiningAccess
->operands()) {
573 MemoryAccess
*Operand
= cast
<MemoryAccess
>(&*Op
);
574 EXPECT_TRUE(MSSA
.isLiveOnEntryDef(Operand
));
577 // Now we try to remove the single valued phi
578 Updater
.removeMemoryAccess(DefiningAccess
);
579 MSSA
.verifyMemorySSA();
580 // Now the load should be a load of live on entry.
581 EXPECT_TRUE(MSSA
.isLiveOnEntryDef(LoadAccess
->getDefiningAccess()));
584 // We had a bug with caching where the walker would report MemoryDef#3's clobber
585 // (below) was MemoryDef#1.
587 // define void @F(i8*) {
588 // %A = alloca i8, i8 1
589 // ; 1 = MemoryDef(liveOnEntry)
590 // store i8 0, i8* %A
591 // ; 2 = MemoryDef(1)
592 // store i8 1, i8* %A
593 // ; 3 = MemoryDef(2)
594 // store i8 2, i8* %A
596 TEST_F(MemorySSATest
, TestTripleStore
) {
597 F
= Function::Create(FunctionType::get(B
.getVoidTy(), {}, false),
598 GlobalValue::ExternalLinkage
, "F", &M
);
599 B
.SetInsertPoint(BasicBlock::Create(C
, "", F
));
600 Type
*Int8
= Type::getInt8Ty(C
);
601 Value
*Alloca
= B
.CreateAlloca(Int8
, ConstantInt::get(Int8
, 1), "A");
602 StoreInst
*S1
= B
.CreateStore(ConstantInt::get(Int8
, 0), Alloca
);
603 StoreInst
*S2
= B
.CreateStore(ConstantInt::get(Int8
, 1), Alloca
);
604 StoreInst
*S3
= B
.CreateStore(ConstantInt::get(Int8
, 2), Alloca
);
607 MemorySSA
&MSSA
= *Analyses
->MSSA
;
608 MemorySSAWalker
*Walker
= Analyses
->Walker
;
611 for (StoreInst
*V
: {S1
, S2
, S3
}) {
612 // Everything should be clobbered by its defining access
613 MemoryAccess
*DefiningAccess
= MSSA
.getMemoryAccess(V
)->getDefiningAccess();
614 MemoryAccess
*WalkerClobber
= Walker
->getClobberingMemoryAccess(V
);
615 EXPECT_EQ(DefiningAccess
, WalkerClobber
)
616 << "Store " << I
<< " doesn't have the correct clobbering access";
617 // EXPECT_EQ expands such that if we increment I above, it won't get
618 // incremented except when we try to print the error message.
623 // ...And fixing the above bug made it obvious that, when walking, MemorySSA's
624 // walker was caching the initial node it walked. This was fine (albeit
625 // mostly redundant) unless the initial node being walked is a clobber for the
626 // query. In that case, we'd cache that the node clobbered itself.
627 TEST_F(MemorySSATest
, TestStoreAndLoad
) {
628 F
= Function::Create(FunctionType::get(B
.getVoidTy(), {}, false),
629 GlobalValue::ExternalLinkage
, "F", &M
);
630 B
.SetInsertPoint(BasicBlock::Create(C
, "", F
));
631 Type
*Int8
= Type::getInt8Ty(C
);
632 Value
*Alloca
= B
.CreateAlloca(Int8
, ConstantInt::get(Int8
, 1), "A");
633 Instruction
*SI
= B
.CreateStore(ConstantInt::get(Int8
, 0), Alloca
);
634 Instruction
*LI
= B
.CreateLoad(Int8
, Alloca
);
637 MemorySSA
&MSSA
= *Analyses
->MSSA
;
638 MemorySSAWalker
*Walker
= Analyses
->Walker
;
640 MemoryAccess
*LoadClobber
= Walker
->getClobberingMemoryAccess(LI
);
641 EXPECT_EQ(LoadClobber
, MSSA
.getMemoryAccess(SI
));
642 EXPECT_TRUE(MSSA
.isLiveOnEntryDef(Walker
->getClobberingMemoryAccess(SI
)));
645 // Another bug (related to the above two fixes): It was noted that, given the
647 // ; 1 = MemoryDef(liveOnEntry)
648 // store i8 0, i8* %1
650 // ...A query to getClobberingMemoryAccess(MemoryAccess*, MemoryLocation) would
651 // hand back the store (correctly). A later call to
652 // getClobberingMemoryAccess(const Instruction*) would also hand back the store
653 // (incorrectly; it should return liveOnEntry).
655 // This test checks that repeated calls to either function returns what they're
657 TEST_F(MemorySSATest
, TestStoreDoubleQuery
) {
658 F
= Function::Create(FunctionType::get(B
.getVoidTy(), {}, false),
659 GlobalValue::ExternalLinkage
, "F", &M
);
660 B
.SetInsertPoint(BasicBlock::Create(C
, "", F
));
661 Type
*Int8
= Type::getInt8Ty(C
);
662 Value
*Alloca
= B
.CreateAlloca(Int8
, ConstantInt::get(Int8
, 1), "A");
663 StoreInst
*SI
= B
.CreateStore(ConstantInt::get(Int8
, 0), Alloca
);
666 MemorySSA
&MSSA
= *Analyses
->MSSA
;
667 MemorySSAWalker
*Walker
= Analyses
->Walker
;
669 MemoryAccess
*StoreAccess
= MSSA
.getMemoryAccess(SI
);
670 MemoryLocation StoreLoc
= MemoryLocation::get(SI
);
671 MemoryAccess
*Clobber
=
672 Walker
->getClobberingMemoryAccess(StoreAccess
, StoreLoc
);
673 MemoryAccess
*LiveOnEntry
= Walker
->getClobberingMemoryAccess(SI
);
675 EXPECT_EQ(Clobber
, StoreAccess
);
676 EXPECT_TRUE(MSSA
.isLiveOnEntryDef(LiveOnEntry
));
678 // Try again (with entries in the cache already) for good measure...
679 Clobber
= Walker
->getClobberingMemoryAccess(StoreAccess
, StoreLoc
);
680 LiveOnEntry
= Walker
->getClobberingMemoryAccess(SI
);
681 EXPECT_EQ(Clobber
, StoreAccess
);
682 EXPECT_TRUE(MSSA
.isLiveOnEntryDef(LiveOnEntry
));
685 // Bug: During phi optimization, the walker wouldn't cache to the proper result
686 // in the farthest-walked BB.
688 // Specifically, it would assume that whatever we walked to was a clobber.
689 // "Whatever we walked to" isn't a clobber if we hit a cache entry.
691 // ...So, we need a test case that looks like:
698 // Where, when we try to optimize a thing in 'C', a blocker is found in 'B'.
699 // The walk must determine that the blocker exists by using cache entries *while
701 TEST_F(MemorySSATest
, PartialWalkerCacheWithPhis
) {
702 F
= Function::Create(FunctionType::get(B
.getVoidTy(), {}, false),
703 GlobalValue::ExternalLinkage
, "F", &M
);
704 B
.SetInsertPoint(BasicBlock::Create(C
, "A", F
));
705 Type
*Int8
= Type::getInt8Ty(C
);
706 Constant
*One
= ConstantInt::get(Int8
, 1);
707 Constant
*Zero
= ConstantInt::get(Int8
, 0);
708 Value
*AllocA
= B
.CreateAlloca(Int8
, One
, "a");
709 Value
*AllocB
= B
.CreateAlloca(Int8
, One
, "b");
710 BasicBlock
*IfThen
= BasicBlock::Create(C
, "B", F
);
711 BasicBlock
*IfEnd
= BasicBlock::Create(C
, "C", F
);
713 B
.CreateCondBr(UndefValue::get(Type::getInt1Ty(C
)), IfThen
, IfEnd
);
715 B
.SetInsertPoint(IfThen
);
716 Instruction
*FirstStore
= B
.CreateStore(Zero
, AllocA
);
717 B
.CreateStore(Zero
, AllocB
);
718 Instruction
*ALoad0
= B
.CreateLoad(Int8
, AllocA
, "");
719 Instruction
*BStore
= B
.CreateStore(Zero
, AllocB
);
720 // Due to use optimization/etc. we make a store to A, which is removed after
721 // we build MSSA. This helps keep the test case simple-ish.
722 Instruction
*KillStore
= B
.CreateStore(Zero
, AllocA
);
723 Instruction
*ALoad
= B
.CreateLoad(Int8
, AllocA
, "");
726 B
.SetInsertPoint(IfEnd
);
727 Instruction
*BelowPhi
= B
.CreateStore(Zero
, AllocA
);
730 MemorySSA
&MSSA
= *Analyses
->MSSA
;
731 MemorySSAWalker
*Walker
= Analyses
->Walker
;
732 MemorySSAUpdater
Updater(&MSSA
);
734 // Kill `KillStore`; it exists solely so that the load after it won't be
735 // optimized to FirstStore.
736 Updater
.removeMemoryAccess(MSSA
.getMemoryAccess(KillStore
));
737 KillStore
->eraseFromParent();
738 auto *ALoadMA
= cast
<MemoryUse
>(MSSA
.getMemoryAccess(ALoad
));
739 EXPECT_EQ(ALoadMA
->getDefiningAccess(), MSSA
.getMemoryAccess(BStore
));
741 // Populate the cache for the store to AllocB directly after FirstStore. It
742 // should point to something in block B (so something in D can't be optimized
744 MemoryAccess
*Load0Clobber
= Walker
->getClobberingMemoryAccess(ALoad0
);
745 EXPECT_EQ(MSSA
.getMemoryAccess(FirstStore
), Load0Clobber
);
747 // If the bug exists, this will introduce a bad cache entry for %a on BStore.
748 // It will point to the store to %b after FirstStore. This only happens during
750 MemoryAccess
*BottomClobber
= Walker
->getClobberingMemoryAccess(BelowPhi
);
751 MemoryAccess
*Phi
= MSSA
.getMemoryAccess(IfEnd
);
752 EXPECT_EQ(BottomClobber
, Phi
);
754 // This query will first check the cache for {%a, BStore}. It should point to
755 // FirstStore, not to the store after FirstStore.
756 MemoryAccess
*UseClobber
= Walker
->getClobberingMemoryAccess(ALoad
);
757 EXPECT_EQ(UseClobber
, MSSA
.getMemoryAccess(FirstStore
));
760 // Test that our walker properly handles loads with the invariant group
761 // attribute. It's a bit hacky, since we add the invariant attribute *after*
762 // building MSSA. Otherwise, the use optimizer will optimize it for us, which
763 // isn't what we want.
764 // FIXME: It may be easier/cleaner to just add an 'optimize uses?' flag to MSSA.
765 TEST_F(MemorySSATest
, WalkerInvariantLoadOpt
) {
766 F
= Function::Create(FunctionType::get(B
.getVoidTy(), {}, false),
767 GlobalValue::ExternalLinkage
, "F", &M
);
768 B
.SetInsertPoint(BasicBlock::Create(C
, "", F
));
769 Type
*Int8
= Type::getInt8Ty(C
);
770 Constant
*One
= ConstantInt::get(Int8
, 1);
771 Value
*AllocA
= B
.CreateAlloca(Int8
, One
, "");
773 Instruction
*Store
= B
.CreateStore(One
, AllocA
);
774 Instruction
*Load
= B
.CreateLoad(Int8
, AllocA
);
777 MemorySSA
&MSSA
= *Analyses
->MSSA
;
778 MemorySSAWalker
*Walker
= Analyses
->Walker
;
780 auto *LoadMA
= cast
<MemoryUse
>(MSSA
.getMemoryAccess(Load
));
781 auto *StoreMA
= cast
<MemoryDef
>(MSSA
.getMemoryAccess(Store
));
782 EXPECT_EQ(LoadMA
->getDefiningAccess(), StoreMA
);
784 // ...At the time of writing, no cache should exist for LoadMA. Be a bit
785 // flexible to future changes.
786 Walker
->invalidateInfo(LoadMA
);
787 Load
->setMetadata(LLVMContext::MD_invariant_load
, MDNode::get(C
, {}));
789 MemoryAccess
*LoadClobber
= Walker
->getClobberingMemoryAccess(LoadMA
);
790 EXPECT_EQ(LoadClobber
, MSSA
.getLiveOnEntryDef());
793 // Test loads get reoptimized properly by the walker.
794 TEST_F(MemorySSATest
, WalkerReopt
) {
795 F
= Function::Create(FunctionType::get(B
.getVoidTy(), {}, false),
796 GlobalValue::ExternalLinkage
, "F", &M
);
797 B
.SetInsertPoint(BasicBlock::Create(C
, "", F
));
798 Type
*Int8
= Type::getInt8Ty(C
);
799 Value
*AllocaA
= B
.CreateAlloca(Int8
, ConstantInt::get(Int8
, 1), "A");
800 Instruction
*SIA
= B
.CreateStore(ConstantInt::get(Int8
, 0), AllocaA
);
801 Value
*AllocaB
= B
.CreateAlloca(Int8
, ConstantInt::get(Int8
, 1), "B");
802 Instruction
*SIB
= B
.CreateStore(ConstantInt::get(Int8
, 0), AllocaB
);
803 Instruction
*LIA
= B
.CreateLoad(Int8
, AllocaA
);
806 MemorySSA
&MSSA
= *Analyses
->MSSA
;
807 MemorySSAWalker
*Walker
= Analyses
->Walker
;
808 MemorySSAUpdater
Updater(&MSSA
);
810 MemoryAccess
*LoadClobber
= Walker
->getClobberingMemoryAccess(LIA
);
811 MemoryUse
*LoadAccess
= cast
<MemoryUse
>(MSSA
.getMemoryAccess(LIA
));
812 EXPECT_EQ(LoadClobber
, MSSA
.getMemoryAccess(SIA
));
813 EXPECT_TRUE(MSSA
.isLiveOnEntryDef(Walker
->getClobberingMemoryAccess(SIA
)));
814 Updater
.removeMemoryAccess(LoadAccess
);
816 // Create the load memory access pointing to an unoptimized place.
817 MemoryUse
*NewLoadAccess
= cast
<MemoryUse
>(Updater
.createMemoryAccessInBB(
818 LIA
, MSSA
.getMemoryAccess(SIB
), LIA
->getParent(), MemorySSA::End
));
819 // This should it cause it to be optimized
820 EXPECT_EQ(Walker
->getClobberingMemoryAccess(NewLoadAccess
), LoadClobber
);
821 EXPECT_EQ(NewLoadAccess
->getDefiningAccess(), LoadClobber
);
824 // Test out MemorySSAUpdater::moveBefore
825 TEST_F(MemorySSATest
, MoveAboveMemoryDef
) {
826 F
= Function::Create(FunctionType::get(B
.getVoidTy(), {}, false),
827 GlobalValue::ExternalLinkage
, "F", &M
);
828 B
.SetInsertPoint(BasicBlock::Create(C
, "", F
));
830 Type
*Int8
= Type::getInt8Ty(C
);
831 Value
*A
= B
.CreateAlloca(Int8
, ConstantInt::get(Int8
, 1), "A");
832 Value
*B_
= B
.CreateAlloca(Int8
, ConstantInt::get(Int8
, 1), "B");
833 Value
*C
= B
.CreateAlloca(Int8
, ConstantInt::get(Int8
, 1), "C");
835 StoreInst
*StoreA0
= B
.CreateStore(ConstantInt::get(Int8
, 0), A
);
836 StoreInst
*StoreB
= B
.CreateStore(ConstantInt::get(Int8
, 0), B_
);
837 LoadInst
*LoadB
= B
.CreateLoad(Int8
, B_
);
838 StoreInst
*StoreA1
= B
.CreateStore(ConstantInt::get(Int8
, 4), A
);
839 StoreInst
*StoreC
= B
.CreateStore(ConstantInt::get(Int8
, 4), C
);
840 StoreInst
*StoreA2
= B
.CreateStore(ConstantInt::get(Int8
, 4), A
);
841 LoadInst
*LoadC
= B
.CreateLoad(Int8
, C
);
844 MemorySSA
&MSSA
= *Analyses
->MSSA
;
845 MemorySSAWalker
&Walker
= *Analyses
->Walker
;
847 MemorySSAUpdater
Updater(&MSSA
);
848 StoreC
->moveBefore(StoreB
);
849 Updater
.moveBefore(cast
<MemoryDef
>(MSSA
.getMemoryAccess(StoreC
)),
850 cast
<MemoryDef
>(MSSA
.getMemoryAccess(StoreB
)));
852 MSSA
.verifyMemorySSA();
854 EXPECT_EQ(MSSA
.getMemoryAccess(StoreB
)->getDefiningAccess(),
855 MSSA
.getMemoryAccess(StoreC
));
856 EXPECT_EQ(MSSA
.getMemoryAccess(StoreC
)->getDefiningAccess(),
857 MSSA
.getMemoryAccess(StoreA0
));
858 EXPECT_EQ(MSSA
.getMemoryAccess(StoreA2
)->getDefiningAccess(),
859 MSSA
.getMemoryAccess(StoreA1
));
860 EXPECT_EQ(Walker
.getClobberingMemoryAccess(LoadB
),
861 MSSA
.getMemoryAccess(StoreB
));
862 EXPECT_EQ(Walker
.getClobberingMemoryAccess(LoadC
),
863 MSSA
.getMemoryAccess(StoreC
));
865 // exercise block numbering
866 EXPECT_TRUE(MSSA
.locallyDominates(MSSA
.getMemoryAccess(StoreC
),
867 MSSA
.getMemoryAccess(StoreB
)));
868 EXPECT_TRUE(MSSA
.locallyDominates(MSSA
.getMemoryAccess(StoreA1
),
869 MSSA
.getMemoryAccess(StoreA2
)));
872 TEST_F(MemorySSATest
, Irreducible
) {
873 // Create the equivalent of
876 // goto second_loop_entry
878 // second_loop_entry:
882 SmallVector
<PHINode
*, 8> Inserted
;
884 F
= Function::Create(
885 FunctionType::get(B
.getVoidTy(), {B
.getInt8PtrTy()}, false),
886 GlobalValue::ExternalLinkage
, "F", &M
);
889 BasicBlock
*IfBB
= BasicBlock::Create(C
, "if", F
);
890 BasicBlock
*LoopStartBB
= BasicBlock::Create(C
, "loopstart", F
);
891 BasicBlock
*LoopMainBB
= BasicBlock::Create(C
, "loopmain", F
);
892 BasicBlock
*AfterLoopBB
= BasicBlock::Create(C
, "afterloop", F
);
893 B
.SetInsertPoint(IfBB
);
894 B
.CreateCondBr(B
.getTrue(), LoopMainBB
, LoopStartBB
);
895 B
.SetInsertPoint(LoopStartBB
);
896 B
.CreateBr(LoopMainBB
);
897 B
.SetInsertPoint(LoopMainBB
);
898 B
.CreateCondBr(B
.getTrue(), LoopStartBB
, AfterLoopBB
);
899 B
.SetInsertPoint(AfterLoopBB
);
900 Argument
*FirstArg
= &*F
->arg_begin();
902 MemorySSA
&MSSA
= *Analyses
->MSSA
;
903 MemorySSAUpdater
Updater(&MSSA
);
904 // Create the load memory acccess
905 LoadInst
*LoadInst
= B
.CreateLoad(B
.getInt8Ty(), FirstArg
);
906 MemoryUse
*LoadAccess
= cast
<MemoryUse
>(Updater
.createMemoryAccessInBB(
907 LoadInst
, nullptr, AfterLoopBB
, MemorySSA::Beginning
));
908 Updater
.insertUse(LoadAccess
);
909 MSSA
.verifyMemorySSA();
912 TEST_F(MemorySSATest
, MoveToBeforeLiveOnEntryInvalidatesCache
) {
915 // ; 1 = MemoryDef(liveOnEntry)
916 // store i8 0, i8* %1
917 // ; 2 = MemoryDef(1)
918 // store i8 0, i8* %1
920 // ...And be sure that MSSA's caching doesn't give us `1` for the clobber of
921 // `2` after `1` is removed.
923 F
= Function::Create(
924 FunctionType::get(B
.getVoidTy(), {B
.getInt8PtrTy()}, false),
925 GlobalValue::ExternalLinkage
, "F", &M
);
927 BasicBlock
*Entry
= BasicBlock::Create(C
, "if", F
);
928 B
.SetInsertPoint(Entry
);
930 Value
*A
= B
.CreateAlloca(B
.getInt8Ty());
931 StoreInst
*StoreA
= B
.CreateStore(B
.getInt8(0), A
);
932 StoreInst
*StoreB
= B
.CreateStore(B
.getInt8(0), A
);
936 MemorySSA
&MSSA
= *Analyses
->MSSA
;
938 auto *DefA
= cast
<MemoryDef
>(MSSA
.getMemoryAccess(StoreA
));
939 auto *DefB
= cast
<MemoryDef
>(MSSA
.getMemoryAccess(StoreB
));
941 MemoryAccess
*BClobber
= MSSA
.getWalker()->getClobberingMemoryAccess(DefB
);
942 ASSERT_EQ(DefA
, BClobber
);
944 MemorySSAUpdater(&MSSA
).removeMemoryAccess(DefA
);
945 StoreA
->eraseFromParent();
947 EXPECT_EQ(DefB
->getDefiningAccess(), MSSA
.getLiveOnEntryDef());
949 EXPECT_EQ(MSSA
.getWalker()->getClobberingMemoryAccess(DefB
),
950 MSSA
.getLiveOnEntryDef())
951 << "(DefA = " << DefA
<< ")";
954 TEST_F(MemorySSATest
, RemovingDefInvalidatesCache
) {
958 // ; 1 = MemoryDef(liveOnEntry)
959 // store i8 0, i8* %x
960 // ; 2 = MemoryDef(1)
961 // store i8 0, i8* %y
962 // ; 3 = MemoryDef(2)
963 // store i8 0, i8* %x
965 // And be sure that MSSA's caching handles the removal of def `1`
968 F
= Function::Create(
969 FunctionType::get(B
.getVoidTy(), {B
.getInt8PtrTy()}, false),
970 GlobalValue::ExternalLinkage
, "F", &M
);
972 BasicBlock
*Entry
= BasicBlock::Create(C
, "if", F
);
973 B
.SetInsertPoint(Entry
);
975 Value
*X
= B
.CreateAlloca(B
.getInt8Ty());
976 Value
*Y
= B
.CreateAlloca(B
.getInt8Ty());
977 StoreInst
*StoreX1
= B
.CreateStore(B
.getInt8(0), X
);
978 StoreInst
*StoreY
= B
.CreateStore(B
.getInt8(0), Y
);
979 StoreInst
*StoreX2
= B
.CreateStore(B
.getInt8(0), X
);
983 MemorySSA
&MSSA
= *Analyses
->MSSA
;
985 auto *DefX1
= cast
<MemoryDef
>(MSSA
.getMemoryAccess(StoreX1
));
986 auto *DefY
= cast
<MemoryDef
>(MSSA
.getMemoryAccess(StoreY
));
987 auto *DefX2
= cast
<MemoryDef
>(MSSA
.getMemoryAccess(StoreX2
));
989 EXPECT_EQ(DefX2
->getDefiningAccess(), DefY
);
990 MemoryAccess
*X2Clobber
= MSSA
.getWalker()->getClobberingMemoryAccess(DefX2
);
991 ASSERT_EQ(DefX1
, X2Clobber
);
993 MemorySSAUpdater(&MSSA
).removeMemoryAccess(DefX1
);
994 StoreX1
->eraseFromParent();
996 EXPECT_EQ(DefX2
->getDefiningAccess(), DefY
);
997 EXPECT_EQ(MSSA
.getWalker()->getClobberingMemoryAccess(DefX2
),
998 MSSA
.getLiveOnEntryDef())
999 << "(DefX1 = " << DefX1
<< ")";
1002 // Test Must alias for optimized uses
1003 TEST_F(MemorySSATest
, TestLoadMustAlias
) {
1004 F
= Function::Create(FunctionType::get(B
.getVoidTy(), {}, false),
1005 GlobalValue::ExternalLinkage
, "F", &M
);
1006 B
.SetInsertPoint(BasicBlock::Create(C
, "", F
));
1007 Type
*Int8
= Type::getInt8Ty(C
);
1008 Value
*AllocaA
= B
.CreateAlloca(Int8
, ConstantInt::get(Int8
, 1), "A");
1009 Value
*AllocaB
= B
.CreateAlloca(Int8
, ConstantInt::get(Int8
, 1), "B");
1011 B
.CreateStore(ConstantInt::get(Int8
, 1), AllocaB
);
1012 // Check load from LOE
1013 LoadInst
*LA1
= B
.CreateLoad(Int8
, AllocaA
, "");
1014 // Check load alias cached for second load
1015 LoadInst
*LA2
= B
.CreateLoad(Int8
, AllocaA
, "");
1017 B
.CreateStore(ConstantInt::get(Int8
, 1), AllocaA
);
1018 // Check load from store/def
1019 LoadInst
*LA3
= B
.CreateLoad(Int8
, AllocaA
, "");
1020 // Check load alias cached for second load
1021 LoadInst
*LA4
= B
.CreateLoad(Int8
, AllocaA
, "");
1024 MemorySSA
&MSSA
= *Analyses
->MSSA
;
1027 for (LoadInst
*V
: {LA1
, LA2
}) {
1028 MemoryUse
*MemUse
= dyn_cast_or_null
<MemoryUse
>(MSSA
.getMemoryAccess(V
));
1029 EXPECT_EQ(MemUse
->getOptimizedAccessType(), None
)
1030 << "Load " << I
<< " doesn't have the correct alias information";
1031 // EXPECT_EQ expands such that if we increment I above, it won't get
1032 // incremented except when we try to print the error message.
1035 for (LoadInst
*V
: {LA3
, LA4
}) {
1036 MemoryUse
*MemUse
= dyn_cast_or_null
<MemoryUse
>(MSSA
.getMemoryAccess(V
));
1037 EXPECT_EQ(MemUse
->getOptimizedAccessType(), MustAlias
)
1038 << "Load " << I
<< " doesn't have the correct alias information";
1039 // EXPECT_EQ expands such that if we increment I above, it won't get
1040 // incremented except when we try to print the error message.
1045 // Test Must alias for optimized defs.
1046 TEST_F(MemorySSATest
, TestStoreMustAlias
) {
1047 F
= Function::Create(FunctionType::get(B
.getVoidTy(), {}, false),
1048 GlobalValue::ExternalLinkage
, "F", &M
);
1049 B
.SetInsertPoint(BasicBlock::Create(C
, "", F
));
1050 Type
*Int8
= Type::getInt8Ty(C
);
1051 Value
*AllocaA
= B
.CreateAlloca(Int8
, ConstantInt::get(Int8
, 1), "A");
1052 Value
*AllocaB
= B
.CreateAlloca(Int8
, ConstantInt::get(Int8
, 1), "B");
1053 StoreInst
*SA1
= B
.CreateStore(ConstantInt::get(Int8
, 1), AllocaA
);
1054 StoreInst
*SB1
= B
.CreateStore(ConstantInt::get(Int8
, 1), AllocaB
);
1055 StoreInst
*SA2
= B
.CreateStore(ConstantInt::get(Int8
, 2), AllocaA
);
1056 StoreInst
*SB2
= B
.CreateStore(ConstantInt::get(Int8
, 2), AllocaB
);
1057 StoreInst
*SA3
= B
.CreateStore(ConstantInt::get(Int8
, 3), AllocaA
);
1058 StoreInst
*SB3
= B
.CreateStore(ConstantInt::get(Int8
, 3), AllocaB
);
1061 MemorySSA
&MSSA
= *Analyses
->MSSA
;
1062 MemorySSAWalker
*Walker
= Analyses
->Walker
;
1065 for (StoreInst
*V
: {SA1
, SB1
, SA2
, SB2
, SA3
, SB3
}) {
1066 MemoryDef
*MemDef
= dyn_cast_or_null
<MemoryDef
>(MSSA
.getMemoryAccess(V
));
1067 EXPECT_EQ(MemDef
->isOptimized(), false)
1068 << "Store " << I
<< " is optimized from the start?";
1069 EXPECT_EQ(MemDef
->getOptimizedAccessType(), MayAlias
)
1071 << " has correct alias information before being optimized?";
1073 Walker
->getClobberingMemoryAccess(V
);
1075 MemoryAccess
*Def
= MemDef
->getDefiningAccess();
1076 MemoryAccess
*Clob
= Walker
->getClobberingMemoryAccess(V
);
1077 EXPECT_NE(Def
, Clob
) << "Store " << I
1078 << " has Defining Access equal to Clobbering Access";
1080 EXPECT_EQ(MemDef
->isOptimized(), true)
1081 << "Store " << I
<< " was not optimized";
1082 if (I
== 0 || I
== 1)
1083 EXPECT_EQ(MemDef
->getOptimizedAccessType(), None
)
1084 << "Store " << I
<< " doesn't have the correct alias information";
1086 EXPECT_EQ(MemDef
->getOptimizedAccessType(), MustAlias
)
1087 << "Store " << I
<< " doesn't have the correct alias information";
1088 // EXPECT_EQ expands such that if we increment I above, it won't get
1089 // incremented except when we try to print the error message.
1094 // Test May alias for optimized uses.
1095 TEST_F(MemorySSATest
, TestLoadMayAlias
) {
1096 F
= Function::Create(FunctionType::get(B
.getVoidTy(),
1097 {B
.getInt8PtrTy(), B
.getInt8PtrTy()},
1099 GlobalValue::ExternalLinkage
, "F", &M
);
1100 B
.SetInsertPoint(BasicBlock::Create(C
, "", F
));
1101 Type
*Int8
= Type::getInt8Ty(C
);
1102 auto *ArgIt
= F
->arg_begin();
1103 Argument
*PointerA
= &*ArgIt
;
1104 Argument
*PointerB
= &*(++ArgIt
);
1105 B
.CreateStore(ConstantInt::get(Int8
, 1), PointerB
);
1106 LoadInst
*LA1
= B
.CreateLoad(Int8
, PointerA
, "");
1107 B
.CreateStore(ConstantInt::get(Int8
, 0), PointerA
);
1108 LoadInst
*LB1
= B
.CreateLoad(Int8
, PointerB
, "");
1109 B
.CreateStore(ConstantInt::get(Int8
, 0), PointerA
);
1110 LoadInst
*LA2
= B
.CreateLoad(Int8
, PointerA
, "");
1111 B
.CreateStore(ConstantInt::get(Int8
, 0), PointerB
);
1112 LoadInst
*LB2
= B
.CreateLoad(Int8
, PointerB
, "");
1115 MemorySSA
&MSSA
= *Analyses
->MSSA
;
1118 for (LoadInst
*V
: {LA1
, LB1
}) {
1119 MemoryUse
*MemUse
= dyn_cast_or_null
<MemoryUse
>(MSSA
.getMemoryAccess(V
));
1120 EXPECT_EQ(MemUse
->getOptimizedAccessType(), MayAlias
)
1121 << "Load " << I
<< " doesn't have the correct alias information";
1122 // EXPECT_EQ expands such that if we increment I above, it won't get
1123 // incremented except when we try to print the error message.
1126 for (LoadInst
*V
: {LA2
, LB2
}) {
1127 MemoryUse
*MemUse
= dyn_cast_or_null
<MemoryUse
>(MSSA
.getMemoryAccess(V
));
1128 EXPECT_EQ(MemUse
->getOptimizedAccessType(), MustAlias
)
1129 << "Load " << I
<< " doesn't have the correct alias information";
1130 // EXPECT_EQ expands such that if we increment I above, it won't get
1131 // incremented except when we try to print the error message.
1136 // Test May alias for optimized defs.
1137 TEST_F(MemorySSATest
, TestStoreMayAlias
) {
1138 F
= Function::Create(FunctionType::get(B
.getVoidTy(),
1139 {B
.getInt8PtrTy(), B
.getInt8PtrTy()},
1141 GlobalValue::ExternalLinkage
, "F", &M
);
1142 B
.SetInsertPoint(BasicBlock::Create(C
, "", F
));
1143 Type
*Int8
= Type::getInt8Ty(C
);
1144 auto *ArgIt
= F
->arg_begin();
1145 Argument
*PointerA
= &*ArgIt
;
1146 Argument
*PointerB
= &*(++ArgIt
);
1147 Value
*AllocaC
= B
.CreateAlloca(Int8
, ConstantInt::get(Int8
, 1), "C");
1148 // Store into arg1, must alias because it's LOE => must
1149 StoreInst
*SA1
= B
.CreateStore(ConstantInt::get(Int8
, 0), PointerA
);
1150 // Store into arg2, may alias store to arg1 => may
1151 StoreInst
*SB1
= B
.CreateStore(ConstantInt::get(Int8
, 1), PointerB
);
1152 // Store into aloca, no alias with args, so must alias LOE => must
1153 StoreInst
*SC1
= B
.CreateStore(ConstantInt::get(Int8
, 2), AllocaC
);
1154 // Store into arg1, may alias store to arg2 => may
1155 StoreInst
*SA2
= B
.CreateStore(ConstantInt::get(Int8
, 3), PointerA
);
1156 // Store into arg2, may alias store to arg1 => may
1157 StoreInst
*SB2
= B
.CreateStore(ConstantInt::get(Int8
, 4), PointerB
);
1158 // Store into aloca, no alias with args, so must alias SC1 => must
1159 StoreInst
*SC2
= B
.CreateStore(ConstantInt::get(Int8
, 5), AllocaC
);
1160 // Store into arg2, must alias store to arg2 => must
1161 StoreInst
*SB3
= B
.CreateStore(ConstantInt::get(Int8
, 6), PointerB
);
1162 std::initializer_list
<StoreInst
*> Sts
= {SA1
, SB1
, SC1
, SA2
, SB2
, SC2
, SB3
};
1165 MemorySSA
&MSSA
= *Analyses
->MSSA
;
1166 MemorySSAWalker
*Walker
= Analyses
->Walker
;
1169 for (StoreInst
*V
: Sts
) {
1170 MemoryDef
*MemDef
= dyn_cast_or_null
<MemoryDef
>(MSSA
.getMemoryAccess(V
));
1171 EXPECT_EQ(MemDef
->isOptimized(), false)
1172 << "Store " << I
<< " is optimized from the start?";
1173 EXPECT_EQ(MemDef
->getOptimizedAccessType(), MayAlias
)
1175 << " has correct alias information before being optimized?";
1179 for (StoreInst
*V
: Sts
)
1180 Walker
->getClobberingMemoryAccess(V
);
1183 for (StoreInst
*V
: Sts
) {
1184 MemoryDef
*MemDef
= dyn_cast_or_null
<MemoryDef
>(MSSA
.getMemoryAccess(V
));
1185 EXPECT_EQ(MemDef
->isOptimized(), true)
1186 << "Store " << I
<< " was not optimized";
1187 if (I
== 1 || I
== 3 || I
== 4)
1188 EXPECT_EQ(MemDef
->getOptimizedAccessType(), MayAlias
)
1189 << "Store " << I
<< " doesn't have the correct alias information";
1190 else if (I
== 0 || I
== 2)
1191 EXPECT_EQ(MemDef
->getOptimizedAccessType(), None
)
1192 << "Store " << I
<< " doesn't have the correct alias information";
1194 EXPECT_EQ(MemDef
->getOptimizedAccessType(), MustAlias
)
1195 << "Store " << I
<< " doesn't have the correct alias information";
1196 // EXPECT_EQ expands such that if we increment I above, it won't get
1197 // incremented except when we try to print the error message.
1202 TEST_F(MemorySSATest
, LifetimeMarkersAreClobbers
) {
1204 // define void @a(i8* %foo) {
1205 // %bar = getelementptr i8, i8* %foo, i64 1
1206 // store i8 0, i8* %foo
1207 // store i8 0, i8* %bar
1208 // call void @llvm.lifetime.end.p0i8(i64 8, i32* %p)
1209 // call void @llvm.lifetime.start.p0i8(i64 8, i32* %p)
1210 // store i8 0, i8* %foo
1211 // store i8 0, i8* %bar
1215 // Patterns like this are possible after inlining; the stores to %foo and %bar
1216 // should both be clobbered by the lifetime.start call if they're dominated by
1220 F
= Function::Create(
1221 FunctionType::get(B
.getVoidTy(), {B
.getInt8PtrTy()}, false),
1222 GlobalValue::ExternalLinkage
, "F", &M
);
1225 BasicBlock
*Entry
= BasicBlock::Create(C
, "entry", F
);
1227 B
.SetInsertPoint(Entry
);
1228 Value
*Foo
= &*F
->arg_begin();
1230 Value
*Bar
= B
.CreateGEP(B
.getInt8Ty(), Foo
, B
.getInt64(1), "bar");
1232 B
.CreateStore(B
.getInt8(0), Foo
);
1233 B
.CreateStore(B
.getInt8(0), Bar
);
1235 auto GetLifetimeIntrinsic
= [&](Intrinsic::ID ID
) {
1236 return Intrinsic::getDeclaration(&M
, ID
, {Foo
->getType()});
1239 B
.CreateCall(GetLifetimeIntrinsic(Intrinsic::lifetime_end
),
1240 {B
.getInt64(2), Foo
});
1241 Instruction
*LifetimeStart
= B
.CreateCall(
1242 GetLifetimeIntrinsic(Intrinsic::lifetime_start
), {B
.getInt64(2), Foo
});
1244 Instruction
*FooStore
= B
.CreateStore(B
.getInt8(0), Foo
);
1245 Instruction
*BarStore
= B
.CreateStore(B
.getInt8(0), Bar
);
1248 MemorySSA
&MSSA
= *Analyses
->MSSA
;
1250 MemoryAccess
*LifetimeStartAccess
= MSSA
.getMemoryAccess(LifetimeStart
);
1251 ASSERT_NE(LifetimeStartAccess
, nullptr);
1253 MemoryAccess
*FooAccess
= MSSA
.getMemoryAccess(FooStore
);
1254 ASSERT_NE(FooAccess
, nullptr);
1256 MemoryAccess
*BarAccess
= MSSA
.getMemoryAccess(BarStore
);
1257 ASSERT_NE(BarAccess
, nullptr);
1259 MemoryAccess
*FooClobber
=
1260 MSSA
.getWalker()->getClobberingMemoryAccess(FooAccess
);
1261 EXPECT_EQ(FooClobber
, LifetimeStartAccess
);
1263 MemoryAccess
*BarClobber
=
1264 MSSA
.getWalker()->getClobberingMemoryAccess(BarAccess
);
1265 EXPECT_EQ(BarClobber
, LifetimeStartAccess
);
1268 TEST_F(MemorySSATest
, DefOptimizationsAreInvalidatedOnMoving
) {
1270 F
= Function::Create(FunctionType::get(B
.getVoidTy(), {B
.getInt1Ty()}, false),
1271 GlobalValue::ExternalLinkage
, "F", &M
);
1280 // Put a def in A and a def in B, move the def from A -> B, observe as the
1281 // optimization is invalidated.
1282 BasicBlock
*Entry
= BasicBlock::Create(C
, "entry", F
);
1283 BasicBlock
*BlockA
= BasicBlock::Create(C
, "a", F
);
1284 BasicBlock
*BlockB
= BasicBlock::Create(C
, "b", F
);
1285 BasicBlock
*BlockC
= BasicBlock::Create(C
, "c", F
);
1287 B
.SetInsertPoint(Entry
);
1288 Type
*Int8
= Type::getInt8Ty(C
);
1289 Value
*Alloca
= B
.CreateAlloca(Int8
, ConstantInt::get(Int8
, 1), "alloc");
1290 StoreInst
*StoreEntry
= B
.CreateStore(B
.getInt8(0), Alloca
);
1291 B
.CreateCondBr(B
.getTrue(), BlockA
, BlockB
);
1293 B
.SetInsertPoint(BlockA
);
1294 StoreInst
*StoreA
= B
.CreateStore(B
.getInt8(1), Alloca
);
1297 B
.SetInsertPoint(BlockB
);
1298 StoreInst
*StoreB
= B
.CreateStore(B
.getInt8(2), Alloca
);
1301 B
.SetInsertPoint(BlockC
);
1302 B
.CreateUnreachable();
1305 MemorySSA
&MSSA
= *Analyses
->MSSA
;
1307 auto *AccessEntry
= cast
<MemoryDef
>(MSSA
.getMemoryAccess(StoreEntry
));
1308 auto *StoreAEntry
= cast
<MemoryDef
>(MSSA
.getMemoryAccess(StoreA
));
1309 auto *StoreBEntry
= cast
<MemoryDef
>(MSSA
.getMemoryAccess(StoreB
));
1311 ASSERT_EQ(MSSA
.getWalker()->getClobberingMemoryAccess(StoreAEntry
),
1313 ASSERT_TRUE(StoreAEntry
->isOptimized());
1315 ASSERT_EQ(MSSA
.getWalker()->getClobberingMemoryAccess(StoreBEntry
),
1317 ASSERT_TRUE(StoreBEntry
->isOptimized());
1319 // Note that if we did InsertionPlace::Beginning, we don't go out of our way
1320 // to invalidate the cache for StoreBEntry. If the user wants to actually do
1321 // moves like these, it's up to them to ensure that nearby cache entries are
1322 // correctly invalidated (which, in general, requires walking all instructions
1323 // that the moved instruction dominates. So we probably shouldn't be doing
1324 // moves like this in general. Still, works as a test-case. ;) )
1325 MemorySSAUpdater(&MSSA
).moveToPlace(StoreAEntry
, BlockB
,
1326 MemorySSA::InsertionPlace::End
);
1327 ASSERT_FALSE(StoreAEntry
->isOptimized());
1328 ASSERT_EQ(MSSA
.getWalker()->getClobberingMemoryAccess(StoreAEntry
),
1332 TEST_F(MemorySSATest
, TestOptimizedDefsAreProperUses
) {
1333 F
= Function::Create(FunctionType::get(B
.getVoidTy(),
1334 {B
.getInt8PtrTy(), B
.getInt8PtrTy()},
1336 GlobalValue::ExternalLinkage
, "F", &M
);
1337 B
.SetInsertPoint(BasicBlock::Create(C
, "", F
));
1338 Type
*Int8
= Type::getInt8Ty(C
);
1339 Value
*AllocA
= B
.CreateAlloca(Int8
, ConstantInt::get(Int8
, 1), "A");
1340 Value
*AllocB
= B
.CreateAlloca(Int8
, ConstantInt::get(Int8
, 1), "B");
1342 StoreInst
*StoreA
= B
.CreateStore(ConstantInt::get(Int8
, 0), AllocA
);
1343 StoreInst
*StoreB
= B
.CreateStore(ConstantInt::get(Int8
, 1), AllocB
);
1344 StoreInst
*StoreA2
= B
.CreateStore(ConstantInt::get(Int8
, 2), AllocA
);
1347 MemorySSA
&MSSA
= *Analyses
->MSSA
;
1348 MemorySSAWalker
*Walker
= Analyses
->Walker
;
1350 // If these don't hold, there's no chance of the test result being useful.
1351 ASSERT_EQ(Walker
->getClobberingMemoryAccess(StoreA
),
1352 MSSA
.getLiveOnEntryDef());
1353 ASSERT_EQ(Walker
->getClobberingMemoryAccess(StoreB
),
1354 MSSA
.getLiveOnEntryDef());
1355 auto *StoreAAccess
= cast
<MemoryDef
>(MSSA
.getMemoryAccess(StoreA
));
1356 auto *StoreA2Access
= cast
<MemoryDef
>(MSSA
.getMemoryAccess(StoreA2
));
1357 ASSERT_EQ(Walker
->getClobberingMemoryAccess(StoreA2
), StoreAAccess
);
1358 ASSERT_EQ(StoreA2Access
->getOptimized(), StoreAAccess
);
1360 auto *StoreBAccess
= cast
<MemoryDef
>(MSSA
.getMemoryAccess(StoreB
));
1361 ASSERT_LT(StoreAAccess
->getID(), StoreBAccess
->getID());
1362 ASSERT_LT(StoreBAccess
->getID(), StoreA2Access
->getID());
1364 auto SortVecByID
= [](std::vector
<const MemoryDef
*> &Defs
) {
1365 llvm::sort(Defs
, [](const MemoryDef
*LHS
, const MemoryDef
*RHS
) {
1366 return LHS
->getID() < RHS
->getID();
1370 auto SortedUserList
= [&](const MemoryDef
*MD
) {
1371 std::vector
<const MemoryDef
*> Result
;
1372 transform(MD
->users(), std::back_inserter(Result
),
1373 [](const User
*U
) { return cast
<MemoryDef
>(U
); });
1374 SortVecByID(Result
);
1378 // Use std::vectors, since they have nice pretty-printing if the test fails.
1379 // Parens are necessary because EXPECT_EQ is a macro, and we have commas in
1380 // our init lists...
1381 EXPECT_EQ(SortedUserList(StoreAAccess
),
1382 (std::vector
<const MemoryDef
*>{StoreBAccess
, StoreA2Access
}));
1384 EXPECT_EQ(SortedUserList(StoreBAccess
),
1385 std::vector
<const MemoryDef
*>{StoreA2Access
});
1387 // StoreAAccess should be present twice, since it uses liveOnEntry for both
1388 // its defining and optimized accesses. This is a bit awkward, and is not
1389 // relied upon anywhere at the moment. If this is painful, we can fix it.
1390 EXPECT_EQ(SortedUserList(cast
<MemoryDef
>(MSSA
.getLiveOnEntryDef())),
1391 (std::vector
<const MemoryDef
*>{StoreAAccess
, StoreAAccess
,
1403 // ; 1 = MemoryDef(liveOnEntry)
1405 // ; 2 = MemoryDef(1)
1407 // ; 3 = MemoryPhi({body, 2}, {header, 1})
1408 // ; 4 = MemoryDef(3); optimized to 3, cannot optimize thorugh phi.
1409 // Insert edge: entry -> exit, check mssa Update is correct.
1410 TEST_F(MemorySSATest
, TestAddedEdgeToBlockWithPhiNotOpt
) {
1411 F
= Function::Create(
1412 FunctionType::get(B
.getVoidTy(), {B
.getInt8PtrTy()}, false),
1413 GlobalValue::ExternalLinkage
, "F", &M
);
1414 Argument
*PointerArg
= &*F
->arg_begin();
1415 BasicBlock
*Entry(BasicBlock::Create(C
, "entry", F
));
1416 BasicBlock
*Header(BasicBlock::Create(C
, "header", F
));
1417 BasicBlock
*Body(BasicBlock::Create(C
, "body", F
));
1418 BasicBlock
*Exit(BasicBlock::Create(C
, "exit", F
));
1419 B
.SetInsertPoint(Entry
);
1420 BranchInst::Create(Header
, Entry
);
1421 B
.SetInsertPoint(Header
);
1422 B
.CreateStore(B
.getInt8(16), PointerArg
);
1423 B
.CreateCondBr(B
.getTrue(), Exit
, Body
);
1424 B
.SetInsertPoint(Body
);
1425 B
.CreateStore(B
.getInt8(16), PointerArg
);
1426 BranchInst::Create(Exit
, Body
);
1427 B
.SetInsertPoint(Exit
);
1428 StoreInst
*S1
= B
.CreateStore(B
.getInt8(16), PointerArg
);
1431 MemorySSA
&MSSA
= *Analyses
->MSSA
;
1432 MemorySSAWalker
*Walker
= Analyses
->Walker
;
1433 std::unique_ptr
<MemorySSAUpdater
> MSSAU
=
1434 std::make_unique
<MemorySSAUpdater
>(&MSSA
);
1436 MemoryPhi
*Phi
= MSSA
.getMemoryAccess(Exit
);
1437 EXPECT_EQ(Phi
, Walker
->getClobberingMemoryAccess(S1
));
1439 // Alter CFG, add edge: entry -> exit
1440 Entry
->getTerminator()->eraseFromParent();
1441 B
.SetInsertPoint(Entry
);
1442 B
.CreateCondBr(B
.getTrue(), Header
, Exit
);
1443 SmallVector
<CFGUpdate
, 1> Updates
;
1444 Updates
.push_back({cfg::UpdateKind::Insert
, Entry
, Exit
});
1445 Analyses
->DT
.applyUpdates(Updates
);
1446 MSSAU
->applyInsertUpdates(Updates
, Analyses
->DT
);
1447 EXPECT_EQ(Phi
, Walker
->getClobberingMemoryAccess(S1
));
1458 // ; 1 = MemoryDef(liveOnEntry)
1460 // ; 2 = MemoryDef(1)
1462 // ; 3 = MemoryPhi({body, 2}, {header, 1})
1463 // ; 4 = MemoryDef(3); optimize this to 1 now, added edge should invalidate
1464 // the optimized access.
1465 // Insert edge: entry -> exit, check mssa Update is correct.
1466 TEST_F(MemorySSATest
, TestAddedEdgeToBlockWithPhiOpt
) {
1467 F
= Function::Create(
1468 FunctionType::get(B
.getVoidTy(), {B
.getInt8PtrTy()}, false),
1469 GlobalValue::ExternalLinkage
, "F", &M
);
1470 Argument
*PointerArg
= &*F
->arg_begin();
1471 Type
*Int8
= Type::getInt8Ty(C
);
1472 BasicBlock
*Entry(BasicBlock::Create(C
, "entry", F
));
1473 BasicBlock
*Header(BasicBlock::Create(C
, "header", F
));
1474 BasicBlock
*Body(BasicBlock::Create(C
, "body", F
));
1475 BasicBlock
*Exit(BasicBlock::Create(C
, "exit", F
));
1477 B
.SetInsertPoint(Entry
);
1478 Value
*Alloca
= B
.CreateAlloca(Int8
, ConstantInt::get(Int8
, 1), "A");
1479 BranchInst::Create(Header
, Entry
);
1481 B
.SetInsertPoint(Header
);
1482 StoreInst
*S1
= B
.CreateStore(B
.getInt8(16), PointerArg
);
1483 B
.CreateCondBr(B
.getTrue(), Exit
, Body
);
1485 B
.SetInsertPoint(Body
);
1486 B
.CreateStore(ConstantInt::get(Int8
, 0), Alloca
);
1487 BranchInst::Create(Exit
, Body
);
1489 B
.SetInsertPoint(Exit
);
1490 StoreInst
*S2
= B
.CreateStore(B
.getInt8(16), PointerArg
);
1493 MemorySSA
&MSSA
= *Analyses
->MSSA
;
1494 MemorySSAWalker
*Walker
= Analyses
->Walker
;
1495 std::unique_ptr
<MemorySSAUpdater
> MSSAU
=
1496 std::make_unique
<MemorySSAUpdater
>(&MSSA
);
1498 MemoryDef
*DefS1
= cast
<MemoryDef
>(MSSA
.getMemoryAccess(S1
));
1499 EXPECT_EQ(DefS1
, Walker
->getClobberingMemoryAccess(S2
));
1501 // Alter CFG, add edge: entry -> exit
1502 Entry
->getTerminator()->eraseFromParent();
1503 B
.SetInsertPoint(Entry
);
1504 B
.CreateCondBr(B
.getTrue(), Header
, Exit
);
1505 SmallVector
<CFGUpdate
, 1> Updates
;
1506 Updates
.push_back({cfg::UpdateKind::Insert
, Entry
, Exit
});
1507 Analyses
->DT
.applyUpdates(Updates
);
1508 MSSAU
->applyInsertUpdates(Updates
, Analyses
->DT
);
1510 MemoryPhi
*Phi
= MSSA
.getMemoryAccess(Exit
);
1511 EXPECT_EQ(Phi
, Walker
->getClobberingMemoryAccess(S2
));
1524 // ; 1 = MemoryDef(liveOnEntry)
1526 // ; 2 = MemoryPhi({d, liveOnEntry}, {f, 1})
1528 // Insert edge: f -> c, check update is correct.
1531 // ; 1 = MemoryDef(liveOnEntry)
1533 // ; 3 = MemoryPhi({a, liveOnEntry}, {f, 1})
1535 // ; 4 = MemoryPhi({b, liveOnEntry}, {c, 3})
1537 // ; 2 = MemoryPhi({d, 4}, {f, 1})
1538 TEST_F(MemorySSATest
, TestAddedEdgeToBlockWithNoPhiAddNewPhis
) {
1539 F
= Function::Create(
1540 FunctionType::get(B
.getVoidTy(), {B
.getInt8PtrTy()}, false),
1541 GlobalValue::ExternalLinkage
, "F", &M
);
1542 Argument
*PointerArg
= &*F
->arg_begin();
1543 BasicBlock
*Entry(BasicBlock::Create(C
, "entry", F
));
1544 BasicBlock
*ABlock(BasicBlock::Create(C
, "a", F
));
1545 BasicBlock
*BBlock(BasicBlock::Create(C
, "b", F
));
1546 BasicBlock
*CBlock(BasicBlock::Create(C
, "c", F
));
1547 BasicBlock
*DBlock(BasicBlock::Create(C
, "d", F
));
1548 BasicBlock
*EBlock(BasicBlock::Create(C
, "e", F
));
1549 BasicBlock
*FBlock(BasicBlock::Create(C
, "f", F
));
1551 B
.SetInsertPoint(Entry
);
1552 B
.CreateCondBr(B
.getTrue(), ABlock
, FBlock
);
1553 B
.SetInsertPoint(ABlock
);
1554 B
.CreateCondBr(B
.getTrue(), BBlock
, CBlock
);
1555 B
.SetInsertPoint(BBlock
);
1556 BranchInst::Create(DBlock
, BBlock
);
1557 B
.SetInsertPoint(CBlock
);
1558 BranchInst::Create(DBlock
, CBlock
);
1559 B
.SetInsertPoint(DBlock
);
1560 BranchInst::Create(EBlock
, DBlock
);
1561 B
.SetInsertPoint(FBlock
);
1562 B
.CreateStore(B
.getInt8(16), PointerArg
);
1563 BranchInst::Create(EBlock
, FBlock
);
1566 MemorySSA
&MSSA
= *Analyses
->MSSA
;
1567 std::unique_ptr
<MemorySSAUpdater
> MSSAU
=
1568 std::make_unique
<MemorySSAUpdater
>(&MSSA
);
1570 // Alter CFG, add edge: f -> c
1571 FBlock
->getTerminator()->eraseFromParent();
1572 B
.SetInsertPoint(FBlock
);
1573 B
.CreateCondBr(B
.getTrue(), CBlock
, EBlock
);
1574 SmallVector
<CFGUpdate
, 1> Updates
;
1575 Updates
.push_back({cfg::UpdateKind::Insert
, FBlock
, CBlock
});
1576 Analyses
->DT
.applyUpdates(Updates
);
1577 MSSAU
->applyInsertUpdates(Updates
, Analyses
->DT
);
1579 MemoryPhi
*MPC
= MSSA
.getMemoryAccess(CBlock
);
1580 EXPECT_NE(MPC
, nullptr);
1581 MemoryPhi
*MPD
= MSSA
.getMemoryAccess(DBlock
);
1582 EXPECT_NE(MPD
, nullptr);
1583 MemoryPhi
*MPE
= MSSA
.getMemoryAccess(EBlock
);
1584 EXPECT_EQ(MPD
, MPE
->getIncomingValueForBlock(DBlock
));