Index: lib/Analysis/CaptureTracking.cpp =================================================================== --- lib/Analysis/CaptureTracking.cpp +++ lib/Analysis/CaptureTracking.cpp @@ -271,6 +271,17 @@ 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)) + if (Tracker->captured(U)) + return; + break; case Instruction::BitCast: case Instruction::GetElementPtr: case Instruction::PHI: Index: test/Transforms/FunctionAttrs/nocapture.ll =================================================================== --- test/Transforms/FunctionAttrs/nocapture.ll +++ test/Transforms/FunctionAttrs/nocapture.ll @@ -193,3 +193,14 @@ ret void } +; CHECK: define void @test_cmpxchg(i32* nocapture %p) +define void @test_cmpxchg(i32* %p) { + cmpxchg i32* %p, i32 0, i32 1 acquire monotonic + ret void +} + +; CHECK: define void @test_atomicrmw(i32* nocapture %p) +define void @test_atomicrmw(i32* %p) { + atomicrmw add i32* %p, i32 1 seq_cst + ret void +}