[llvm] r270879 - [CaptureTracking] Volatile operations capture their memory location
David Majnemer via llvm-commits
llvm-commits at lists.llvm.org
Thu May 26 10:36:22 PDT 2016
Author: majnemer
Date: Thu May 26 12:36:22 2016
New Revision: 270879
URL: http://llvm.org/viewvc/llvm-project?rev=270879&view=rev
Log:
[CaptureTracking] Volatile operations capture their memory location
The memory location that corresponds to a volatile operation is very
special. They are observed by the machine in ways which we cannot
reason about.
Differential Revision: http://reviews.llvm.org/D20555
Modified:
llvm/trunk/docs/LangRef.rst
llvm/trunk/lib/Analysis/CaptureTracking.cpp
llvm/trunk/test/Transforms/FunctionAttrs/nocapture.ll
Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=270879&r1=270878&r2=270879&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Thu May 26 12:36:22 2016
@@ -1037,7 +1037,8 @@ Currently, only the following parameter
``nocapture``
This indicates that the callee does not make any copies of the
pointer that outlive the callee itself. This is not a valid
- attribute for return values.
+ attribute for return values. Addresses used in volatile operations
+ are considered to be captured.
.. _nest:
Modified: llvm/trunk/lib/Analysis/CaptureTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CaptureTracking.cpp?rev=270879&r1=270878&r2=270879&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/CaptureTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/CaptureTracking.cpp Thu May 26 12:36:22 2016
@@ -26,6 +26,7 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
using namespace llvm;
@@ -242,6 +243,13 @@ void llvm::PointerMayBeCaptured(const Va
if (CS.onlyReadsMemory() && CS.doesNotThrow() && I->getType()->isVoidTy())
break;
+ // Volatile operations effectively capture the memory location that they
+ // load and store to.
+ if (auto *MI = dyn_cast<MemIntrinsic>(I))
+ if (MI->isVolatile())
+ if (Tracker->captured(U))
+ return;
+
// Not captured if only passed via 'nocapture' arguments. Note that
// calling a function pointer does not in itself cause the pointer to
// be captured. This is a subtle point considering that (for example)
@@ -259,29 +267,46 @@ void llvm::PointerMayBeCaptured(const Va
break;
}
case Instruction::Load:
- // Loading from a pointer does not cause it to be captured.
+ // Volatile loads make the address observable.
+ if (cast<LoadInst>(I)->isVolatile())
+ if (Tracker->captured(U))
+ return;
break;
case Instruction::VAArg:
// "va-arg" from a pointer does not cause it to be captured.
break;
case Instruction::Store:
- if (V == I->getOperand(0))
// Stored the pointer - conservatively assume it may be captured.
+ // Volatile stores make the address observable.
+ if (V == I->getOperand(0) || cast<StoreInst>(I)->isVolatile())
if (Tracker->captured(U))
return;
- // Storing to the pointee does not cause the pointer to be captured.
break;
- case Instruction::AtomicRMW:
- case Instruction::AtomicCmpXchg:
- // atomicrmw and cmpxchg conceptually include both a load and store from
- // the same location. As with a store, the location being accessed is
- // not captured, but the value being stored is. (For cmpxchg, we
- // probably don't need to capture the original comparison value, but for
- // the moment, let's be conservative.)
- if (V != I->getOperand(0))
+ case Instruction::AtomicRMW: {
+ // atomicrmw conceptually includes both a load and store from
+ // the same location.
+ // As with a store, the location being accessed is not captured,
+ // but the value being stored is.
+ // Volatile stores make the address observable.
+ auto *ARMWI = cast<AtomicRMWInst>(I);
+ if (ARMWI->getValOperand() == V || ARMWI->isVolatile())
if (Tracker->captured(U))
return;
break;
+ }
+ case Instruction::AtomicCmpXchg: {
+ // cmpxchg conceptually includes both a load and store from
+ // the same location.
+ // As with a store, the location being accessed is not captured,
+ // but the value being stored is.
+ // Volatile stores make the address observable.
+ auto *ACXI = cast<AtomicCmpXchgInst>(I);
+ if (ACXI->getCompareOperand() == V || ACXI->getNewValOperand() == V ||
+ ACXI->isVolatile())
+ if (Tracker->captured(U))
+ return;
+ break;
+ }
case Instruction::BitCast:
case Instruction::GetElementPtr:
case Instruction::PHI:
Modified: llvm/trunk/test/Transforms/FunctionAttrs/nocapture.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/FunctionAttrs/nocapture.ll?rev=270879&r1=270878&r2=270879&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/FunctionAttrs/nocapture.ll (original)
+++ llvm/trunk/test/Transforms/FunctionAttrs/nocapture.ll Thu May 26 12:36:22 2016
@@ -210,3 +210,11 @@ define void @test_atomicrmw(i32* %p) {
atomicrmw add i32* %p, i32 1 seq_cst
ret void
}
+
+; CHECK: define void @test_volatile(i32* %x)
+define void @test_volatile(i32* %x) {
+entry:
+ %gep = getelementptr i32, i32* %x, i64 1
+ store volatile i32 0, i32* %gep, align 4
+ ret void
+}
More information about the llvm-commits
mailing list