From a85a66423d966bf6210daf9587dba7ec1ff8d64e Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Wed, 28 Oct 2009 06:30:52 +0000 Subject: [PATCH] Be more careful about invariance reasoning on "store" queries. Stores still need to depend on Ref and ModRef calls within the invariant region. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@85380 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/MemoryDependenceAnalysis.cpp | 15 +++++++++------ test/Transforms/GVN/invariant-simple.ll | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp index edead091ed4..be5f9c1ae04 100644 --- a/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -230,12 +230,11 @@ getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad, return MemDepResult::getDef(Inst); } - // If we're querying on a store and we're in an invariant region, we're done - // at this point. The only things that stores depend on that could exist in - // an invariant region are loads, which we've already checked. - if (invariantTag) continue; - if (StoreInst *SI = dyn_cast(Inst)) { + // There can't be stores to the value we care about inside an + // invariant region. + if (invariantTag) continue; + // If alias analysis can tell that this store is guaranteed to not modify // the query pointer, ignore it. Use getModRefInfo to handle cases where // the query pointer points to constant memory etc. @@ -280,12 +279,16 @@ getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad, case AliasAnalysis::NoModRef: // If the call has no effect on the queried pointer, just ignore it. continue; + case AliasAnalysis::Mod: + // If we're in an invariant region, we can ignore calls that ONLY + // modify the pointer. + if (invariantTag) continue; + return MemDepResult::getClobber(Inst); case AliasAnalysis::Ref: // If the call is known to never store to the pointer, and if this is a // load query, we can safely ignore it (scan past it). if (isLoad) continue; - // FALL THROUGH. default: // Otherwise, there is a potential dependence. Return a clobber. return MemDepResult::getClobber(Inst); diff --git a/test/Transforms/GVN/invariant-simple.ll b/test/Transforms/GVN/invariant-simple.ll index c3ff353833b..6de75f14350 100644 --- a/test/Transforms/GVN/invariant-simple.ll +++ b/test/Transforms/GVN/invariant-simple.ll @@ -16,6 +16,21 @@ entry: ret i8 %2 } +define i8 @test2(i8* %P) nounwind { +; CHECK: @test2 +; CHECK: store i8 1 +; CHECK: store i8 2 +; CHECK: ret i8 0 +entry: + store i8 1, i8* %P + %0 = call {}* @llvm.invariant.start(i64 32, i8* %P) + %1 = tail call i32 @bar(i8* %P) + call void @llvm.invariant.end({}* %0, i64 32, i8* %P) + store i8 2, i8* %P + ret i8 0 +} + declare i32 @foo(i8*) nounwind +declare i32 @bar(i8*) nounwind readonly declare {}* @llvm.invariant.start(i64 %S, i8* nocapture %P) readonly declare void @llvm.invariant.end({}* %S, i64 %SS, i8* nocapture %P) \ No newline at end of file