@@ -26,9 +26,9 @@ using namespace llvm;
2626
2727// Set up some test passes.
2828namespace llvm {
29- void initializeAATestPassPass (PassRegistry&);
30- void initializeTestCustomAAWrapperPassPass (PassRegistry&);
31- }
29+ void initializeAATestPassPass (PassRegistry &);
30+ void initializeTestCustomAAWrapperPassPass (PassRegistry &);
31+ } // namespace llvm
3232
3333namespace {
3434struct AATestPass : FunctionPass {
@@ -61,7 +61,7 @@ struct AATestPass : FunctionPass {
6161 return false ;
6262 }
6363};
64- }
64+ } // namespace
6565
6666char AATestPass::ID = 0 ;
6767INITIALIZE_PASS_BEGIN (AATestPass, " aa-test-pas" , " Alias Analysis Test Pass" ,
@@ -90,7 +90,7 @@ struct TestCustomAAResult : AAResultBase {
9090 return AliasResult::MayAlias;
9191 }
9292};
93- }
93+ } // namespace
9494
9595namespace {
9696// / A wrapper pass for the legacy pass manager to use with the above custom AA
@@ -126,14 +126,14 @@ class TestCustomAAWrapperPass : public ImmutablePass {
126126 TestCustomAAResult &getResult () { return *Result; }
127127 const TestCustomAAResult &getResult () const { return *Result; }
128128};
129- }
129+ } // namespace
130130
131131char TestCustomAAWrapperPass::ID = 0 ;
132132INITIALIZE_PASS_BEGIN (TestCustomAAWrapperPass, " test-custom-aa" ,
133- " Test Custom AA Wrapper Pass" , false , true )
133+ " Test Custom AA Wrapper Pass" , false , true )
134134INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
135135INITIALIZE_PASS_END(TestCustomAAWrapperPass, " test-custom-aa" ,
136- " Test Custom AA Wrapper Pass" , false , true )
136+ " Test Custom AA Wrapper Pass" , false , true )
137137
138138namespace {
139139
@@ -246,7 +246,8 @@ TEST_F(AliasAnalysisTest, BatchAAPhiCycles) {
246246 %s2 = select i1 %c, i8* %a2, i8* %a1
247247 br label %loop
248248 }
249- )" , Err, C);
249+ )" ,
250+ Err, C);
250251
251252 Function *F = M->getFunction (" f" );
252253 Instruction *Phi = getInstructionByName (*F, " phi" );
@@ -291,7 +292,8 @@ TEST_F(AliasAnalysisTest, BatchAAPhiAssumption) {
291292 %b.next = getelementptr i8, i8* %b, i64 1
292293 br label %loop
293294 }
294- )" , Err, C);
295+ )" ,
296+ Err, C);
295297
296298 Function *F = M->getFunction (" f" );
297299 Instruction *A = getInstructionByName (*F, " a" );
@@ -425,4 +427,79 @@ TEST_F(AAPassInfraTest, injectExternalAA) {
425427 EXPECT_TRUE (IsCustomAAQueried);
426428}
427429
428- } // end anonymous namspace
430+ // Test that a monotonic atomic load is treated as ModRef ONLY against a
431+ // MustAlias locations, and as Ref against a MayAlias location.
432+ TEST_F (AliasAnalysisTest, MonotonicAtomicLoadIsModRefOnlyForMustAlias) {
433+ LLVMContext C;
434+ SMDiagnostic Err;
435+ std::unique_ptr<Module> M = parseAssemblyString (R"(
436+ define void @atomic_load_modref_test(i8* %p1, i8* %p2) {
437+ entry:
438+ %val = load atomic i8, i8* %p1 monotonic, align 1
439+ ret void
440+ }
441+ )" ,
442+ Err, C);
443+
444+ ASSERT_TRUE (M);
445+
446+ Function *F = M->getFunction (" atomic_load_modref_test" );
447+ const Instruction *AtomicLoad = &F->getEntryBlock ().front ();
448+ const Value *Ptr1 = F->getArg (0 );
449+ const Value *Ptr2 = F->getArg (1 );
450+
451+ MemoryLocation Ptr1Loc = MemoryLocation (Ptr1, LocationSize::precise (1 ));
452+ MemoryLocation Ptr2Loc = MemoryLocation (Ptr2, LocationSize::precise (1 ));
453+
454+ auto &AA = getAAResults (*F);
455+
456+ // 1. MustAlias Case: The atomic load on %p1 against a location on %p1.
457+ // This should trigger the new logic and return ModRef.
458+ EXPECT_EQ (ModRefInfo::ModRef, AA.getModRefInfo (AtomicLoad, Ptr1Loc));
459+
460+ // 2. MayAlias Case: The atomic load on %p1 against a location on %p2.
461+ // This should NOT trigger the new logic and should fall back to returning
462+ // Ref.
463+ EXPECT_EQ (ModRefInfo::Ref, AA.getModRefInfo (AtomicLoad, Ptr2Loc));
464+ }
465+
466+ // Test that a monotonic atomic store is no longer considered "strong" and
467+ // falls through to the alias checking logic, while stroner orderings do not.
468+ TEST_F (AliasAnalysisTest, MonotonicAtomicStoreAliasBehavior) {
469+ LLVMContext C;
470+ SMDiagnostic Err;
471+ std::unique_ptr<Module> M = parseAssemblyString (R"(
472+ define void @atomic_store_test(i8* noalias %p1, i8* noalias %p2) {
473+ entry:
474+ store atomic i8 0, i8* %p1 monotonic, align 1
475+ store atomic i8 0, i8* %p1 release, align 1
476+ ret void
477+ }
478+ )" ,
479+ Err, C);
480+
481+ ASSERT_TRUE (M);
482+
483+ Function *F = M->getFunction (" atomic_store_test" );
484+ auto It = F->getEntryBlock ().begin ();
485+ const Instruction *MonotonicStore = &*It++;
486+ const Instruction *ReleaseStore = &*It;
487+
488+ const Value *Ptr2 = F->getArg (1 );
489+ MemoryLocation Ptr2Loc = MemoryLocation (Ptr2, LocationSize::precise (1 ));
490+
491+ auto &AA = getAAResults (*F);
492+
493+ // 1. Test the Monotonic store.
494+ // With the change, the Monotonic store should go through the
495+ // isStrongerThan() check. Since %p1 and %p2 are noalias, the alias check
496+ // should return NoAlias, resulting in NoModRef.
497+ EXPECT_EQ (ModRefInfo::NoModRef, AA.getModRefInfo (MonotonicStore, Ptr2Loc));
498+
499+ // 2. Test the Relase (stronger) store.
500+ // The release atomic store should be caught by the isStrongerThan() check.
501+ // return ModRef without performing an alias check.
502+ EXPECT_EQ (ModRefInfo::ModRef, AA.getModRefInfo (ReleaseStore, Ptr2Loc));
503+ }
504+
505+ } // namespace
0 commit comments