diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp index b6ebc6326365..c757eb327d02 100644 --- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp @@ -463,6 +463,11 @@ determinePointerReadAttrs(Argument *A, } case Instruction::Load: + // A volatile load has side effects beyond what readonly can be relied + // upon. + if (cast(I)->isVolatile()) + return Attribute::None; + IsRead = true; break; diff --git a/llvm/test/Transforms/FunctionAttrs/readattrs.ll b/llvm/test/Transforms/FunctionAttrs/readattrs.ll index 4626cb197486..ed2a8aa07ae8 100644 --- a/llvm/test/Transforms/FunctionAttrs/readattrs.ll +++ b/llvm/test/Transforms/FunctionAttrs/readattrs.ll @@ -104,3 +104,11 @@ define <4 x i32> @test12_2(<4 x i32*> %ptrs) { %res = call <4 x i32> @test12_1(<4 x i32*> %ptrs) ret <4 x i32> %res } + +; CHECK: define i32 @volatile_load( +; CHECK-NOT: readonly +; CHECK: ret +define i32 @volatile_load(i32* %p) { + %load = load volatile i32, i32* %p + ret i32 %load +}