diff options
-rw-r--r-- | lib/Analysis/IPA/GlobalsModRef.cpp | 14 | ||||
-rw-r--r-- | test/Analysis/GlobalsModRef/2008-09-13-VolatileRead.ll | 9 |
2 files changed, 20 insertions, 3 deletions
diff --git a/lib/Analysis/IPA/GlobalsModRef.cpp b/lib/Analysis/IPA/GlobalsModRef.cpp index 390a602..74327d5 100644 --- a/lib/Analysis/IPA/GlobalsModRef.cpp +++ b/lib/Analysis/IPA/GlobalsModRef.cpp @@ -431,12 +431,20 @@ void GlobalsModRef::AnalyzeCallGraph(CallGraph &CG, Module &M) { for (inst_iterator II = inst_begin(SCC[i]->getFunction()), E = inst_end(SCC[i]->getFunction()); II != E && FunctionEffect != ModRef; ++II) - if (isa<LoadInst>(*II)) + if (isa<LoadInst>(*II)) { FunctionEffect |= Ref; - else if (isa<StoreInst>(*II)) + if (cast<LoadInst>(*II).isVolatile()) + // Volatile loads may have side-effects, so mark them as writing + // memory (for example, a flag inside the processor). + FunctionEffect |= Mod; + } else if (isa<StoreInst>(*II)) { FunctionEffect |= Mod; - else if (isa<MallocInst>(*II) || isa<FreeInst>(*II)) + if (cast<StoreInst>(*II).isVolatile()) + // Treat volatile stores as reading memory somewhere. + FunctionEffect |= Ref; + } else if (isa<MallocInst>(*II) || isa<FreeInst>(*II)) { FunctionEffect |= ModRef; + } if ((FunctionEffect & Mod) == 0) ++NumReadMemFunctions; diff --git a/test/Analysis/GlobalsModRef/2008-09-13-VolatileRead.ll b/test/Analysis/GlobalsModRef/2008-09-13-VolatileRead.ll new file mode 100644 index 0000000..8ac9637 --- /dev/null +++ b/test/Analysis/GlobalsModRef/2008-09-13-VolatileRead.ll @@ -0,0 +1,9 @@ +; RUN: llvm-as < %s | opt -globalsmodref-aa -markmodref | llvm-dis | not grep read +; PR2792 + +@g = global i32 0 ; <i32*> [#uses=1] + +define i32 @f() { + %t = volatile load i32* @g ; <i32> [#uses=1] + ret i32 %t +} |