Index: lib/Transforms/IPO/FunctionAttrs.cpp =================================================================== --- lib/Transforms/IPO/FunctionAttrs.cpp +++ lib/Transforms/IPO/FunctionAttrs.cpp @@ -205,6 +205,11 @@ // No change. continue; + if (F->getIntrinsicID() == Intrinsic::assume) + // don't change attributes of the assume intrinsic, + // so that later on, it is not thrown away by other optimizations + continue; + MadeChange = true; // Clear out any existing attributes. Index: test/Transforms/FunctionAttrs/assume.ll =================================================================== --- test/Transforms/FunctionAttrs/assume.ll +++ test/Transforms/FunctionAttrs/assume.ll @@ -0,0 +1,29 @@ +; RUN: opt -functionattrs -S < %s | FileCheck %s +; RUN: opt -functionattrs -instcombine -S < %s | FileCheck %s -check-prefix=ASSUME +; +; Ensures that llvm.assume: +; is not marked with readnone attribute. +; is not considered as accessing memory for the purposes of function attributes computation. + +;CHECK: declare void @llvm.assume(i1) #0 +declare void @llvm.assume(i1) + +;CHECK: define i32 @foo(i32 %x) #1 +;ASSUME: define i32 @foo(i32 %x) +define i32 @foo(i32 %x) { +entry: + %cmp = icmp eq i32 %x, 2 + call void @llvm.assume(i1 %cmp) +;ASSUME: ret i32 2 + ret i32 %x +} + +;CHECK: define i32 @foo2(i32 %x) #1 +define i32 @foo2(i32 %x) { +entry: + %foo.x = call i32 @foo(i32 %x) + ret i32 %foo.x +} + +;CHECK: attributes #0 = { nounwind } +;CHECK: attributes #1 = { readnone }