diff options
author | Owen Anderson <resistor@mac.com> | 2009-10-28 06:30:52 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2009-10-28 06:30:52 +0000 |
commit | fc16e5a98f691d3fb290f30f5089c48764de372e (patch) | |
tree | 62cfc8d623d931069bab25aa744621b6cda227ec | |
parent | f64db3e1d05b76e045b0700bfff4476574c00df0 (diff) | |
download | bcm5719-llvm-fc16e5a98f691d3fb290f30f5089c48764de372e.tar.gz bcm5719-llvm-fc16e5a98f691d3fb290f30f5089c48764de372e.zip |
Be more careful about invariance reasoning on "store" queries. Stores still need
to depend on Ref and ModRef calls within the invariant region.
llvm-svn: 85380
-rw-r--r-- | llvm/lib/Analysis/MemoryDependenceAnalysis.cpp | 15 | ||||
-rw-r--r-- | llvm/test/Transforms/GVN/invariant-simple.ll | 15 |
2 files changed, 24 insertions, 6 deletions
diff --git a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp index edead091ed4..be5f9c1ae04 100644 --- a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/llvm/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<StoreInst>(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/llvm/test/Transforms/GVN/invariant-simple.ll b/llvm/test/Transforms/GVN/invariant-simple.ll index c3ff353833b..6de75f14350 100644 --- a/llvm/test/Transforms/GVN/invariant-simple.ll +++ b/llvm/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 |