]> granicus.if.org Git - llvm/commitdiff
[Analysis] Fix isSafeToLoadUnconditionally handling of volatile.
authorEli Friedman <efriedma@codeaurora.org>
Thu, 24 Jan 2019 21:31:13 +0000 (21:31 +0000)
committerEli Friedman <efriedma@codeaurora.org>
Thu, 24 Jan 2019 21:31:13 +0000 (21:31 +0000)
A volatile operation cannot be used to prove an address points to normal
memory.  (LangRef was recently updated to state it explicitly.)

Differential Revision: https://reviews.llvm.org/D57040

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@352109 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/Loads.cpp
test/Transforms/SROA/phi-and-select.ll

index ba4f759a17bb09ddc3bb0ae33ecae6e30fa67296..7da9bd718a51cb5d059a66a6a5236f25bbcc8ca5 100644 (file)
@@ -280,9 +280,17 @@ bool llvm::isSafeToLoadUnconditionally(Value *V, unsigned Align,
     Value *AccessedPtr;
     unsigned AccessedAlign;
     if (LoadInst *LI = dyn_cast<LoadInst>(BBI)) {
+      // Ignore volatile loads. The execution of a volatile load cannot
+      // be used to prove an address is backed by regular memory; it can,
+      // for example, point to an MMIO register.
+      if (LI->isVolatile())
+        continue;
       AccessedPtr = LI->getPointerOperand();
       AccessedAlign = LI->getAlignment();
     } else if (StoreInst *SI = dyn_cast<StoreInst>(BBI)) {
+      // Ignore volatile stores (see comment for loads).
+      if (SI->isVolatile())
+        continue;
       AccessedPtr = SI->getPointerOperand();
       AccessedAlign = SI->getAlignment();
     } else
index e7ba2e89d7956d5356ca845db9e938bd11cec881..d0904cecd9f18a24bb1c1a62c1851ec4133b53ea 100644 (file)
@@ -632,3 +632,15 @@ exit:
   %result = load i32, i32* %phi, align 4
   ret i32 %result
 }
+
+; Don't speculate a load based on an earlier volatile operation.
+define i8 @volatile_select(i8* %p, i1 %b) {
+; CHECK-LABEL: @volatile_select(
+; CHECK: select i1 %b, i8* %p, i8* %p2
+  %p2 = alloca i8
+  store i8 0, i8* %p2
+  store volatile i8 0, i8* %p
+  %px = select i1 %b, i8* %p, i8* %p2
+  %v2 = load i8, i8* %px
+  ret i8 %v2
+}