Index: lib/Analysis/MemoryDependenceAnalysis.cpp =================================================================== --- lib/Analysis/MemoryDependenceAnalysis.cpp +++ lib/Analysis/MemoryDependenceAnalysis.cpp @@ -625,7 +625,7 @@ // Atomic stores have complications involved. // A Monotonic store is OK if the query inst is itself not atomic. // FIXME: This is overly conservative. - if (!SI->isUnordered()) { + if (!SI->isUnordered() && SI->isAtomic()) { if (!QueryInst) return MemDepResult::getClobber(SI); if (SI->getOrdering() != Monotonic) @@ -645,8 +645,15 @@ // While volatile access cannot be eliminated, they do not have to clobber // non-aliasing locations, as normal accesses can for example be reordered // with volatile accesses. - if (SI->isVolatile()) - return MemDepResult::getClobber(SI); + if (QueryInst && SI->isVolatile()) { + if (LoadInst *QLI = dyn_cast(QueryInst)) { + if (!QLI->isSimple()) + return MemDepResult::getClobber(SI); + } else if (StoreInst *QSI = dyn_cast(QueryInst)) { + if (!QSI->isSimple()) + return MemDepResult::getClobber(SI); + } + } // If alias analysis can tell that this store is guaranteed to not modify // the query pointer, ignore it. Use getModRefInfo to handle cases where Index: test/Transforms/GVN/volatile-nonvolatile.ll =================================================================== --- /dev/null +++ test/Transforms/GVN/volatile-nonvolatile.ll @@ -0,0 +1,27 @@ +; RUN: opt -tbaa -gvn -S < %s | FileCheck %s +; Check that we can eliminate the second load. +; CHECK: load +; CHECK-NOT: load + +%struct.t = type { i32* } + +define void @foo(%struct.t* nocapture readonly %p, i32 %v) #0 { +entry: + %m = getelementptr inbounds %struct.t, %struct.t* %p, i32 0, i32 0 + %0 = load i32*, i32** %m, align 4, !tbaa !1 + store volatile i32 %v, i32* %0, align 4, !tbaa !6 + %1 = load i32*, i32** %m, align 4, !tbaa !1 + store volatile i32 %v, i32* %1, align 4, !tbaa !6 + ret void +} + +attributes #0 = { norecurse nounwind } + +!1 = !{!2, !3, i64 0} +!2 = !{!"", !3, i64 0} +!3 = !{!"any pointer", !4, i64 0} +!4 = !{!"omnipotent char", !5, i64 0} +!5 = !{!"Simple C/C++ TBAA"} +!6 = !{!7, !7, i64 0} +!7 = !{!"int", !4, i64 0} +