diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h index 9e9c5862073..d71ba208a12 100644 --- a/include/llvm/Analysis/AliasAnalysis.h +++ b/include/llvm/Analysis/AliasAnalysis.h @@ -136,6 +136,8 @@ public: Location getLocation(const LoadInst *LI); Location getLocation(const StoreInst *SI); Location getLocation(const VAArgInst *VI); + Location getLocation(const AtomicCmpXchgInst *CXI); + Location getLocation(const AtomicRMWInst *RMWI); static Location getLocationForSource(const MemTransferInst *MTI); static Location getLocationForDest(const MemIntrinsic *MI); @@ -426,10 +428,7 @@ public: /// getModRefInfo (for cmpxchges) - Return whether information about whether /// a particular cmpxchg modifies or reads the specified memory location. - ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, const Location &Loc) { - // Conservatively correct. (But there are obvious ways to be smarter.) - return ModRef; - } + ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, const Location &Loc); /// getModRefInfo (for cmpxchges) - A convenience wrapper. ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, @@ -439,10 +438,7 @@ public: /// getModRefInfo (for atomicrmws) - Return whether information about whether /// a particular atomicrmw modifies or reads the specified memory location. - ModRefResult getModRefInfo(const AtomicRMWInst *RMW, const Location &Loc) { - // Conservatively correct. (But there are obvious ways to be smarter.) - return ModRef; - } + ModRefResult getModRefInfo(const AtomicRMWInst *RMW, const Location &Loc); /// getModRefInfo (for atomicrmws) - A convenience wrapper. ModRefResult getModRefInfo(const AtomicRMWInst *RMW, diff --git a/lib/Analysis/AliasAnalysis.cpp b/lib/Analysis/AliasAnalysis.cpp index 73cc9037216..bd132c05c32 100644 --- a/lib/Analysis/AliasAnalysis.cpp +++ b/lib/Analysis/AliasAnalysis.cpp @@ -237,6 +237,19 @@ AliasAnalysis::Location AliasAnalysis::getLocation(const VAArgInst *VI) { VI->getMetadata(LLVMContext::MD_tbaa)); } +AliasAnalysis::Location +AliasAnalysis::getLocation(const AtomicCmpXchgInst *CXI) { + return Location(CXI->getPointerOperand(), + getTypeStoreSize(CXI->getCompareOperand()->getType()), + CXI->getMetadata(LLVMContext::MD_tbaa)); +} + +AliasAnalysis::Location +AliasAnalysis::getLocation(const AtomicRMWInst *RMWI) { + return Location(RMWI->getPointerOperand(), + getTypeStoreSize(RMWI->getValOperand()->getType()), + RMWI->getMetadata(LLVMContext::MD_tbaa)); +} AliasAnalysis::Location AliasAnalysis::getLocationForSource(const MemTransferInst *MTI) { @@ -317,6 +330,33 @@ AliasAnalysis::getModRefInfo(const VAArgInst *V, const Location &Loc) { return ModRef; } +AliasAnalysis::ModRefResult +AliasAnalysis::getModRefInfo(const AtomicCmpXchgInst *CX, const Location &Loc) { + // Acquire/Release cmpxchg has properties that matter for arbitrary addresses. + if (CX->getOrdering() > Monotonic) + return ModRef; + + // If the cmpxchg address does not alias the location, it does not access it. + if (!alias(getLocation(CX), Loc)) + return NoModRef; + + return ModRef; +} + +AliasAnalysis::ModRefResult +AliasAnalysis::getModRefInfo(const AtomicRMWInst *RMW, const Location &Loc) { + // Acquire/Release atomicrmw has properties that matter for arbitrary addresses. + if (RMW->getOrdering() > Monotonic) + return ModRef; + + // If the atomicrmw address does not alias the location, it does not access it. + if (!alias(getLocation(RMW), Loc)) + return NoModRef; + + return ModRef; +} + + // AliasAnalysis destructor: DO NOT move this to the header file for // AliasAnalysis or else clients of the AliasAnalysis class may not depend on // the AliasAnalysis.o file in the current .a file, causing alias analysis diff --git a/test/Analysis/BasicAA/2009-10-13-AtomicModRef.ll b/test/Analysis/BasicAA/2009-10-13-AtomicModRef.ll index 5078dd53a79..4b6a12e821e 100644 --- a/test/Analysis/BasicAA/2009-10-13-AtomicModRef.ll +++ b/test/Analysis/BasicAA/2009-10-13-AtomicModRef.ll @@ -1,14 +1,12 @@ ; RUN: opt -basicaa -gvn -instcombine -S < %s | FileCheck %s target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" -declare i8 @llvm.atomic.load.add.i8.p0i8(i8*, i8) - define i8 @foo(i8* %ptr) { %P = getelementptr i8* %ptr, i32 0 %Q = getelementptr i8* %ptr, i32 1 ; CHECK: getelementptr %X = load i8* %P - %Y = call i8 @llvm.atomic.load.add.i8.p0i8(i8* %Q, i8 1) + %Y = atomicrmw add i8* %Q, i8 1 monotonic %Z = load i8* %P ; CHECK-NOT: = load %A = sub i8 %X, %Z diff --git a/test/Analysis/BasicAA/cas.ll b/test/Analysis/BasicAA/cas.ll index 8dd3695d6d5..754309cd81b 100644 --- a/test/Analysis/BasicAA/cas.ll +++ b/test/Analysis/BasicAA/cas.ll @@ -6,10 +6,8 @@ define i32 @main() { %a = load i32* @flag0 - %b = tail call i32 @llvm.atomic.swap.i32.p0i32(i32* @turn, i32 1) + %b = atomicrmw xchg i32* @turn, i32 1 monotonic %c = load i32* @flag0 %d = sub i32 %a, %c ret i32 %d } - -declare i32 @llvm.atomic.swap.i32.p0i32(i32*, i32) nounwind