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;
--- /dev/null
+; 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
+}