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 52 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 63 void setupAnalyses() { 64 assert(F); 65 Analyses.reset(new TestAnalyses(*this)); 66 } 67 68 public: 69 MemorySSATest() 70 : M("MemorySSATest", C), B(C), DL(DLString), TLI(TLII), F(nullptr) {} 71 }; 72 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 } 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 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 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 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 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 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 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 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 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 // } 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. 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. 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'. 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. 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. 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 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 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 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 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 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. 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. 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. 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 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 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 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. 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. 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}) 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 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 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