1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

[Local] Treat calls that may not return as being alive.

With the addition of the `willreturn` attribute, functions that may
not return (e.g. due to an infinite loop) are well defined, if they are
not marked as `willreturn`.

This patch updates `wouldInstructionBeTriviallyDead` to not consider
calls that may not return as dead.

This patch still provides an escape hatch for intrinsics, which are
still assumed as willreturn unconditionally. It will be removed once
all intrinsics definitions have been reviewed and updated.

Reviewed By: jdoerfert

Differential Revision: https://reviews.llvm.org/D94106
This commit is contained in:
Florian Hahn 2021-01-23 12:42:46 +00:00
parent dbeacbd88e
commit 283961f4c8
29 changed files with 235 additions and 213 deletions

View File

@ -1756,6 +1756,10 @@ public:
bool onlyReadsMemory() const { bool onlyReadsMemory() const {
return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly); return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly);
} }
/// Returns true if this function is guaranteed to return.
bool willReturn() const { return hasFnAttr(Attribute::WillReturn); }
void setOnlyReadsMemory() { void setOnlyReadsMemory() {
addAttribute(AttributeList::FunctionIndex, Attribute::ReadOnly); addAttribute(AttributeList::FunctionIndex, Attribute::ReadOnly);
} }

View File

@ -420,6 +420,14 @@ bool llvm::wouldInstructionBeTriviallyDead(Instruction *I,
return true; return true;
} }
if (auto *CB = dyn_cast<CallBase>(I)) {
// Treat calls that may not return as alive.
// TODO: Remove the intrinsic escape hatch once all intrinsics set
// willreturn properly.
if (!CB->willReturn() && !isa<IntrinsicInst>(I))
return false;
}
if (!I->mayHaveSideEffects()) if (!I->mayHaveSideEffects())
return true; return true;

View File

@ -5,8 +5,8 @@
; they're carrying unknown operand bundles since the presence of ; they're carrying unknown operand bundles since the presence of
; unknown operand bundles implies arbitrary memory effects. ; unknown operand bundles implies arbitrary memory effects.
declare void @readonly_function() readonly nounwind declare void @readonly_function() readonly nounwind willreturn
declare void @readnone_function() readnone nounwind declare void @readnone_function() readnone nounwind willreturn
define i32 @test0(i32* %x) { define i32 @test0(i32* %x) {
; CHECK-LABEL: @test0( ; CHECK-LABEL: @test0(

View File

@ -17,16 +17,32 @@ target triple = "x86_64-unknown-linux-gnu"
@a = internal global %struct.Foo { i32 1, i64 2 }, align 8 @a = internal global %struct.Foo { i32 1, i64 2 }, align 8
define void @run() { define void @run() {
; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone ; IS________OPM: Function Attrs: nofree noreturn nosync nounwind readnone
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@run ; IS________OPM-LABEL: define {{[^@]+}}@run
; NOT_CGSCC_NPM-SAME: () [[ATTR0:#.*]] { ; IS________OPM-SAME: () [[ATTR0:#.*]] {
; NOT_CGSCC_NPM-NEXT: entry: ; IS________OPM-NEXT: entry:
; NOT_CGSCC_NPM-NEXT: unreachable ; IS________OPM-NEXT: [[TMP0:%.*]] = call i64 @CaptureAStruct(%struct.Foo* nocapture nofree noundef nonnull readonly align 8 dereferenceable(16) @a) [[ATTR0]]
; IS________OPM-NEXT: unreachable
;
; IS__TUNIT_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@run
; IS__TUNIT_NPM-SAME: () [[ATTR0:#.*]] {
; IS__TUNIT_NPM-NEXT: entry:
; IS__TUNIT_NPM-NEXT: [[A_CAST:%.*]] = bitcast %struct.Foo* @a to i32*
; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_CAST]], align 8
; IS__TUNIT_NPM-NEXT: [[A_0_1:%.*]] = getelementptr [[STRUCT_FOO:%.*]], %struct.Foo* @a, i32 0, i32 1
; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i64, i64* [[A_0_1]], align 8
; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = call i64 @CaptureAStruct(i32 [[TMP0]], i64 [[TMP1]]) [[ATTR0]]
; IS__TUNIT_NPM-NEXT: unreachable
; ;
; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readonly willreturn ; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readonly willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@run ; IS__CGSCC____-LABEL: define {{[^@]+}}@run
; IS__CGSCC____-SAME: () [[ATTR0:#.*]] { ; IS__CGSCC____-SAME: () [[ATTR0:#.*]] {
; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[A_CAST:%.*]] = bitcast %struct.Foo* @a to i32*
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_CAST]], align 8
; IS__CGSCC____-NEXT: [[A_0_1:%.*]] = getelementptr [[STRUCT_FOO:%.*]], %struct.Foo* @a, i32 0, i32 1
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i64, i64* [[A_0_1]], align 8
; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____-NEXT: unreachable
; ;
entry: entry:
@ -86,6 +102,37 @@ define internal i64 @CaptureAStruct(%struct.Foo* byval(%struct.Foo) %a) {
; IS__CGSCC_OPM-NEXT: [[GEP]] = getelementptr [[STRUCT_FOO:%.*]], %struct.Foo* [[A]], i64 0 ; IS__CGSCC_OPM-NEXT: [[GEP]] = getelementptr [[STRUCT_FOO:%.*]], %struct.Foo* [[A]], i64 0
; IS__CGSCC_OPM-NEXT: br label [[LOOP]] ; IS__CGSCC_OPM-NEXT: br label [[LOOP]]
; ;
; IS________OPM: Function Attrs: nofree noreturn nosync nounwind readnone
; IS________OPM-LABEL: define {{[^@]+}}@CaptureAStruct
; IS________OPM-SAME: (%struct.Foo* noalias nofree noundef nonnull byval(%struct.Foo) align 8 dereferenceable(16) [[A:%.*]]) [[ATTR0]] {
; IS________OPM-NEXT: entry:
; IS________OPM-NEXT: [[A_PTR:%.*]] = alloca %struct.Foo*, align 8
; IS________OPM-NEXT: br label [[LOOP:%.*]]
; IS________OPM: loop:
; IS________OPM-NEXT: [[PHI:%.*]] = phi %struct.Foo* [ null, [[ENTRY:%.*]] ], [ [[GEP:%.*]], [[LOOP]] ]
; IS________OPM-NEXT: [[TMP0:%.*]] = phi %struct.Foo* [ [[A]], [[ENTRY]] ], [ [[TMP0]], [[LOOP]] ]
; IS________OPM-NEXT: store %struct.Foo* [[PHI]], %struct.Foo** [[A_PTR]], align 8
; IS________OPM-NEXT: [[GEP]] = getelementptr [[STRUCT_FOO:%.*]], %struct.Foo* [[A]], i64 0
; IS________OPM-NEXT: br label [[LOOP]]
;
; IS__TUNIT_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@CaptureAStruct
; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]]) [[ATTR0]] {
; IS__TUNIT_NPM-NEXT: entry:
; IS__TUNIT_NPM-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_FOO:%.*]], align 8
; IS__TUNIT_NPM-NEXT: [[A_PRIV_CAST:%.*]] = bitcast %struct.Foo* [[A_PRIV]] to i32*
; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[A_PRIV_CAST]], align 4
; IS__TUNIT_NPM-NEXT: [[A_PRIV_0_1:%.*]] = getelementptr [[STRUCT_FOO]], %struct.Foo* [[A_PRIV]], i32 0, i32 1
; IS__TUNIT_NPM-NEXT: store i64 [[TMP1]], i64* [[A_PRIV_0_1]], align 8
; IS__TUNIT_NPM-NEXT: [[A_PTR:%.*]] = alloca %struct.Foo*, align 8
; IS__TUNIT_NPM-NEXT: br label [[LOOP:%.*]]
; IS__TUNIT_NPM: loop:
; IS__TUNIT_NPM-NEXT: [[PHI:%.*]] = phi %struct.Foo* [ null, [[ENTRY:%.*]] ], [ [[GEP:%.*]], [[LOOP]] ]
; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = phi %struct.Foo* [ [[A_PRIV]], [[ENTRY]] ], [ [[TMP2]], [[LOOP]] ]
; IS__TUNIT_NPM-NEXT: store %struct.Foo* [[PHI]], %struct.Foo** [[A_PTR]], align 8
; IS__TUNIT_NPM-NEXT: [[GEP]] = getelementptr [[STRUCT_FOO]], %struct.Foo* [[A_PRIV]], i64 0
; IS__TUNIT_NPM-NEXT: br label [[LOOP]]
;
; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone ; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone
; IS__CGSCC____-LABEL: define {{[^@]+}}@CaptureAStruct ; IS__CGSCC____-LABEL: define {{[^@]+}}@CaptureAStruct
; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]]) [[ATTR2:#.*]] { ; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]]) [[ATTR2:#.*]] {

View File

@ -102,30 +102,34 @@ define i32* @test5_2() {
; TEST 6 ; TEST 6
; SCC ; SCC
define i32* @test6_1() #0 { define i32* @test6_1() #0 {
; NOT_CGSCC_NPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable ; NOT_CGSCC_OPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test6_1 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test6_1
; NOT_CGSCC_NPM-SAME: () [[ATTR1:#.*]] { ; NOT_CGSCC_OPM-SAME: () [[ATTR1:#.*]] {
; NOT_CGSCC_NPM-NEXT: unreachable ; NOT_CGSCC_OPM-NEXT: [[RET:%.*]] = tail call i32* @test6_2() [[ATTR11:#.*]]
; NOT_CGSCC_OPM-NEXT: unreachable
; ;
; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn ; IS__CGSCC_OPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test6_1 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test6_1
; IS__CGSCC_NPM-SAME: () [[ATTR1:#.*]] { ; IS__CGSCC_OPM-SAME: () [[ATTR1:#.*]] {
; IS__CGSCC_NPM-NEXT: unreachable ; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = tail call i32* @test6_2() [[ATTR12:#.*]]
; IS__CGSCC_OPM-NEXT: unreachable
; ;
%ret = tail call i32* @test6_2() %ret = tail call i32* @test6_2()
ret i32* %ret ret i32* %ret
} }
define i32* @test6_2() #0 { define i32* @test6_2() #0 {
; NOT_CGSCC_NPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable ; NOT_CGSCC_OPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test6_2 ; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test6_2
; NOT_CGSCC_NPM-SAME: () [[ATTR1]] { ; NOT_CGSCC_OPM-SAME: () [[ATTR1]] {
; NOT_CGSCC_NPM-NEXT: unreachable ; NOT_CGSCC_OPM-NEXT: [[RET:%.*]] = tail call i32* @test6_1() [[ATTR11]]
; NOT_CGSCC_OPM-NEXT: unreachable
; ;
; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn ; IS__CGSCC_OPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test6_2 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test6_2
; IS__CGSCC_NPM-SAME: () [[ATTR1]] { ; IS__CGSCC_OPM-SAME: () [[ATTR1]] {
; IS__CGSCC_NPM-NEXT: unreachable ; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = tail call i32* @test6_1() [[ATTR12]]
; IS__CGSCC_OPM-NEXT: unreachable
; ;
%ret = tail call i32* @test6_1() %ret = tail call i32* @test6_1()
ret i32* %ret ret i32* %ret
@ -967,7 +971,7 @@ define i32 @musttail_caller_1(i32* %p) {
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1 ; IS__CGSCC_OPM-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1
; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]] ; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]]
; IS__CGSCC_OPM: mt: ; IS__CGSCC_OPM: mt:
; IS__CGSCC_OPM-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree nonnull readonly dereferenceable(4) [[P]]) [[ATTR12:#.*]] ; IS__CGSCC_OPM-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree nonnull readonly dereferenceable(4) [[P]]) [[ATTR13:#.*]]
; IS__CGSCC_OPM-NEXT: ret i32 [[V]] ; IS__CGSCC_OPM-NEXT: ret i32 [[V]]
; IS__CGSCC_OPM: exit: ; IS__CGSCC_OPM: exit:
; IS__CGSCC_OPM-NEXT: ret i32 0 ; IS__CGSCC_OPM-NEXT: ret i32 0
@ -978,7 +982,7 @@ define i32 @musttail_caller_1(i32* %p) {
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1 ; IS__CGSCC_NPM-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1
; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]] ; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]]
; IS__CGSCC_NPM: mt: ; IS__CGSCC_NPM: mt:
; IS__CGSCC_NPM-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree nonnull readonly dereferenceable(4) [[P]]) [[ATTR11:#.*]] ; IS__CGSCC_NPM-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree nonnull readonly dereferenceable(4) [[P]]) [[ATTR12:#.*]]
; IS__CGSCC_NPM-NEXT: ret i32 [[V]] ; IS__CGSCC_NPM-NEXT: ret i32 [[V]]
; IS__CGSCC_NPM: exit: ; IS__CGSCC_NPM: exit:
; IS__CGSCC_NPM-NEXT: ret i32 0 ; IS__CGSCC_NPM-NEXT: ret i32 0

View File

@ -849,6 +849,8 @@ define void @ptr_uses(i8* %ptr, i8* %wptr) {
; CHECK: Function Attrs: nounwind ; CHECK: Function Attrs: nounwind
; CHECK-LABEL: define {{[^@]+}}@ptr_uses ; CHECK-LABEL: define {{[^@]+}}@ptr_uses
; CHECK-SAME: (i8* [[PTR:%.*]], i8* nocapture nonnull writeonly dereferenceable(1) [[WPTR:%.*]]) [[ATTR13:#.*]] { ; CHECK-SAME: (i8* [[PTR:%.*]], i8* nocapture nonnull writeonly dereferenceable(1) [[WPTR:%.*]]) [[ATTR13:#.*]] {
; CHECK-NEXT: [[CALL_PTR:%.*]] = call i8* @maybe_returned_ptr(i8* readonly [[PTR]]) [[ATTR4]]
; CHECK-NEXT: [[CALL_VAL:%.*]] = call i8 @maybe_returned_val(i8* readonly [[CALL_PTR]]) [[ATTR4]]
; CHECK-NEXT: store i8 0, i8* [[WPTR]], align 1 ; CHECK-NEXT: store i8 0, i8* [[WPTR]], align 1
; CHECK-NEXT: ret void ; CHECK-NEXT: ret void
; ;

View File

@ -728,7 +728,7 @@ define i32* @not_captured_by_readonly_call_not_returned_either3(i32* %b, i32* %r
; CHECK-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either3 ; CHECK-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either3
; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) [[ATTR8]] { ; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) [[ATTR8]] {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1b(i32* nocapture readonly [[B]], i32* readonly [[R]]) [[ATTR6]] ; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1b(i32* nocapture readonly [[B]], i32* readonly [[R]]) [[ATTR8]]
; CHECK-NEXT: ret i32* [[CALL]] ; CHECK-NEXT: ret i32* [[CALL]]
; ;
entry: entry:

View File

@ -149,11 +149,13 @@ define i8* @test4_helper() {
; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone ; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test4_helper ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test4_helper
; NOT_CGSCC_NPM-SAME: () [[ATTR2:#.*]] { ; NOT_CGSCC_NPM-SAME: () [[ATTR2:#.*]] {
; NOT_CGSCC_NPM-NEXT: [[RET:%.*]] = call i8* @test4()
; NOT_CGSCC_NPM-NEXT: unreachable ; NOT_CGSCC_NPM-NEXT: unreachable
; ;
; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn ; IS__CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test4_helper ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test4_helper
; IS__CGSCC_NPM-SAME: () [[ATTR2:#.*]] { ; IS__CGSCC_NPM-SAME: () [[ATTR2:#.*]] {
; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i8* @test4()
; IS__CGSCC_NPM-NEXT: unreachable ; IS__CGSCC_NPM-NEXT: unreachable
; ;
%ret = call i8* @test4() %ret = call i8* @test4()
@ -164,11 +166,13 @@ define i8* @test4() {
; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone ; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test4 ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test4
; NOT_CGSCC_NPM-SAME: () [[ATTR2]] { ; NOT_CGSCC_NPM-SAME: () [[ATTR2]] {
; NOT_CGSCC_NPM-NEXT: [[RET:%.*]] = call i8* @test4_helper()
; NOT_CGSCC_NPM-NEXT: unreachable ; NOT_CGSCC_NPM-NEXT: unreachable
; ;
; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn ; IS__CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test4 ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test4
; IS__CGSCC_NPM-SAME: () [[ATTR2]] { ; IS__CGSCC_NPM-SAME: () [[ATTR2]] {
; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i8* @test4_helper()
; IS__CGSCC_NPM-NEXT: unreachable ; IS__CGSCC_NPM-NEXT: unreachable
; ;
%ret = call i8* @test4_helper() %ret = call i8* @test4_helper()

View File

@ -34,29 +34,21 @@ define i32 @self_rec() {
} }
define i32 @indirect_rec() { define i32 @indirect_rec() {
; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone ; CHECK: Function Attrs: nofree noreturn nosync nounwind readnone
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@indirect_rec ; CHECK-LABEL: define {{[^@]+}}@indirect_rec
; NOT_CGSCC_NPM-SAME: () [[ATTR2:#.*]] { ; CHECK-SAME: () [[ATTR2:#.*]] {
; NOT_CGSCC_NPM-NEXT: unreachable ; CHECK-NEXT: [[A:%.*]] = call i32 @indirect_rec2() [[ATTR2]]
; ; CHECK-NEXT: unreachable
; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@indirect_rec
; IS__CGSCC_NPM-SAME: () [[ATTR1:#.*]] {
; IS__CGSCC_NPM-NEXT: unreachable
; ;
%a = call i32 @indirect_rec2() %a = call i32 @indirect_rec2()
ret i32 %a ret i32 %a
} }
define i32 @indirect_rec2() { define i32 @indirect_rec2() {
; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone ; CHECK: Function Attrs: nofree noreturn nosync nounwind readnone
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@indirect_rec2 ; CHECK-LABEL: define {{[^@]+}}@indirect_rec2
; NOT_CGSCC_NPM-SAME: () [[ATTR2]] { ; CHECK-SAME: () [[ATTR2]] {
; NOT_CGSCC_NPM-NEXT: unreachable ; CHECK-NEXT: [[A:%.*]] = call i32 @indirect_rec() [[ATTR2]]
; ; CHECK-NEXT: unreachable
; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@indirect_rec2
; IS__CGSCC_NPM-SAME: () [[ATTR1]] {
; IS__CGSCC_NPM-NEXT: unreachable
; ;
%a = call i32 @indirect_rec() %a = call i32 @indirect_rec()
ret i32 %a ret i32 %a
@ -65,7 +57,7 @@ define i32 @indirect_rec2() {
define i32 @extern() { define i32 @extern() {
; CHECK: Function Attrs: nosync readnone ; CHECK: Function Attrs: nosync readnone
; CHECK-LABEL: define {{[^@]+}}@extern ; CHECK-LABEL: define {{[^@]+}}@extern
; CHECK-SAME: () [[ATTR2:#.*]] { ; CHECK-SAME: () [[ATTR3:#.*]] {
; CHECK-NEXT: [[A:%.*]] = call i32 @k() ; CHECK-NEXT: [[A:%.*]] = call i32 @k()
; CHECK-NEXT: ret i32 [[A]] ; CHECK-NEXT: ret i32 [[A]]
; ;
@ -78,17 +70,11 @@ define i32 @extern() {
declare i32 @k() readnone declare i32 @k() readnone
define void @intrinsic(i8* %dest, i8* %src, i32 %len) { define void @intrinsic(i8* %dest, i8* %src, i32 %len) {
; NOT_CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn ; CHECK: Function Attrs: argmemonly nofree nosync nounwind willreturn
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@intrinsic ; CHECK-LABEL: define {{[^@]+}}@intrinsic
; NOT_CGSCC_NPM-SAME: (i8* nocapture nofree writeonly [[DEST:%.*]], i8* nocapture nofree readonly [[SRC:%.*]], i32 [[LEN:%.*]]) [[ATTR5:#.*]] { ; CHECK-SAME: (i8* nocapture nofree writeonly [[DEST:%.*]], i8* nocapture nofree readonly [[SRC:%.*]], i32 [[LEN:%.*]]) [[ATTR5:#.*]] {
; NOT_CGSCC_NPM-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree writeonly [[DEST]], i8* noalias nocapture nofree readonly [[SRC]], i32 [[LEN]], i1 noundef false) [[ATTR10:#.*]] ; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree writeonly [[DEST]], i8* noalias nocapture nofree readonly [[SRC]], i32 [[LEN]], i1 noundef false) [[ATTR10:#.*]]
; NOT_CGSCC_NPM-NEXT: ret void ; CHECK-NEXT: ret void
;
; IS__CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@intrinsic
; IS__CGSCC_NPM-SAME: (i8* nocapture nofree writeonly [[DEST:%.*]], i8* nocapture nofree readonly [[SRC:%.*]], i32 [[LEN:%.*]]) [[ATTR4:#.*]] {
; IS__CGSCC_NPM-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree writeonly [[DEST]], i8* noalias nocapture nofree readonly [[SRC]], i32 [[LEN]], i1 noundef false) [[ATTR7:#.*]]
; IS__CGSCC_NPM-NEXT: ret void
; ;
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 false) call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 false)
ret void ret void
@ -107,7 +93,7 @@ define internal i32 @called_by_norecurse() {
; ;
; IS__CGSCC____: Function Attrs: norecurse nosync readnone ; IS__CGSCC____: Function Attrs: norecurse nosync readnone
; IS__CGSCC____-LABEL: define {{[^@]+}}@called_by_norecurse ; IS__CGSCC____-LABEL: define {{[^@]+}}@called_by_norecurse
; IS__CGSCC____-SAME: () [[ATTR5:#.*]] { ; IS__CGSCC____-SAME: () [[ATTR6:#.*]] {
; IS__CGSCC____-NEXT: [[A:%.*]] = call i32 @k() ; IS__CGSCC____-NEXT: [[A:%.*]] = call i32 @k()
; IS__CGSCC____-NEXT: ret i32 undef ; IS__CGSCC____-NEXT: ret i32 undef
; ;
@ -123,7 +109,7 @@ define void @m() norecurse {
; ;
; IS__CGSCC____: Function Attrs: norecurse nosync readnone ; IS__CGSCC____: Function Attrs: norecurse nosync readnone
; IS__CGSCC____-LABEL: define {{[^@]+}}@m ; IS__CGSCC____-LABEL: define {{[^@]+}}@m
; IS__CGSCC____-SAME: () [[ATTR5]] { ; IS__CGSCC____-SAME: () [[ATTR6]] {
; IS__CGSCC____-NEXT: [[A:%.*]] = call i32 @called_by_norecurse() ; IS__CGSCC____-NEXT: [[A:%.*]] = call i32 @called_by_norecurse()
; IS__CGSCC____-NEXT: ret void ; IS__CGSCC____-NEXT: ret void
; ;
@ -134,7 +120,7 @@ define void @m() norecurse {
define internal i32 @called_by_norecurse_indirectly() { define internal i32 @called_by_norecurse_indirectly() {
; CHECK: Function Attrs: nosync readnone ; CHECK: Function Attrs: nosync readnone
; CHECK-LABEL: define {{[^@]+}}@called_by_norecurse_indirectly ; CHECK-LABEL: define {{[^@]+}}@called_by_norecurse_indirectly
; CHECK-SAME: () [[ATTR2]] { ; CHECK-SAME: () [[ATTR3]] {
; CHECK-NEXT: [[A:%.*]] = call i32 @k() ; CHECK-NEXT: [[A:%.*]] = call i32 @k()
; CHECK-NEXT: ret i32 [[A]] ; CHECK-NEXT: ret i32 [[A]]
; ;
@ -150,7 +136,7 @@ define internal i32 @o() {
; ;
; IS__CGSCC____: Function Attrs: norecurse nosync readnone ; IS__CGSCC____: Function Attrs: norecurse nosync readnone
; IS__CGSCC____-LABEL: define {{[^@]+}}@o ; IS__CGSCC____-LABEL: define {{[^@]+}}@o
; IS__CGSCC____-SAME: () [[ATTR5]] { ; IS__CGSCC____-SAME: () [[ATTR6]] {
; IS__CGSCC____-NEXT: [[A:%.*]] = call i32 @called_by_norecurse_indirectly() ; IS__CGSCC____-NEXT: [[A:%.*]] = call i32 @called_by_norecurse_indirectly()
; IS__CGSCC____-NEXT: ret i32 [[A]] ; IS__CGSCC____-NEXT: ret i32 [[A]]
; ;
@ -166,7 +152,7 @@ define i32 @p() norecurse {
; ;
; IS__CGSCC____: Function Attrs: norecurse nosync readnone ; IS__CGSCC____: Function Attrs: norecurse nosync readnone
; IS__CGSCC____-LABEL: define {{[^@]+}}@p ; IS__CGSCC____-LABEL: define {{[^@]+}}@p
; IS__CGSCC____-SAME: () [[ATTR5]] { ; IS__CGSCC____-SAME: () [[ATTR6]] {
; IS__CGSCC____-NEXT: [[A:%.*]] = call i32 @o() ; IS__CGSCC____-NEXT: [[A:%.*]] = call i32 @o()
; IS__CGSCC____-NEXT: ret i32 [[A]] ; IS__CGSCC____-NEXT: ret i32 [[A]]
; ;
@ -175,48 +161,20 @@ define i32 @p() norecurse {
} }
define void @f(i32 %x) { define void @f(i32 %x) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone ; CHECK: Function Attrs: nofree nosync nounwind readnone
; IS__TUNIT____-LABEL: define {{[^@]+}}@f ; CHECK-LABEL: define {{[^@]+}}@f
; IS__TUNIT____-SAME: (i32 [[X:%.*]]) [[ATTR7:#.*]] { ; CHECK-SAME: (i32 [[X:%.*]]) [[ATTR7:#.*]] {
; IS__TUNIT____-NEXT: entry: ; CHECK-NEXT: entry:
; IS__TUNIT____-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4 ; CHECK-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
; IS__TUNIT____-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4 ; CHECK-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 4 ; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 4
; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
; IS__TUNIT____-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; IS__TUNIT____: if.then: ; CHECK: if.then:
; IS__TUNIT____-NEXT: call void @g() [[ATTR8:#.*]] ; CHECK-NEXT: call void @g() [[ATTR8:#.*]]
; IS__TUNIT____-NEXT: br label [[IF_END]] ; CHECK-NEXT: br label [[IF_END]]
; IS__TUNIT____: if.end: ; CHECK: if.end:
; IS__TUNIT____-NEXT: ret void ; CHECK-NEXT: ret void
;
; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f
; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) [[ATTR7:#.*]] {
; IS__CGSCC_OPM-NEXT: entry:
; IS__CGSCC_OPM-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
; IS__CGSCC_OPM-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 4
; IS__CGSCC_OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
; IS__CGSCC_OPM-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; IS__CGSCC_OPM: if.then:
; IS__CGSCC_OPM-NEXT: br label [[IF_END]]
; IS__CGSCC_OPM: if.end:
; IS__CGSCC_OPM-NEXT: ret void
;
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f
; IS__CGSCC_NPM-SAME: (i32 [[X:%.*]]) [[ATTR0:#.*]] {
; IS__CGSCC_NPM-NEXT: entry:
; IS__CGSCC_NPM-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
; IS__CGSCC_NPM-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 4
; IS__CGSCC_NPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
; IS__CGSCC_NPM-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; IS__CGSCC_NPM: if.then:
; IS__CGSCC_NPM-NEXT: br label [[IF_END]]
; IS__CGSCC_NPM: if.end:
; IS__CGSCC_NPM-NEXT: ret void
; ;
entry: entry:
%x.addr = alloca i32, align 4 %x.addr = alloca i32, align 4
@ -234,24 +192,12 @@ if.end:
} }
define void @g() norecurse { define void @g() norecurse {
; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone
; IS__TUNIT____-LABEL: define {{[^@]+}}@g ; CHECK-LABEL: define {{[^@]+}}@g
; IS__TUNIT____-SAME: () [[ATTR8]] { ; CHECK-SAME: () [[ATTR8]] {
; IS__TUNIT____-NEXT: entry: ; CHECK-NEXT: entry:
; IS__TUNIT____-NEXT: ret void ; CHECK-NEXT: call void @f(i32 noundef 0) [[ATTR7]]
; ; CHECK-NEXT: ret void
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@g
; IS__CGSCC_OPM-SAME: () [[ATTR8:#.*]] {
; IS__CGSCC_OPM-NEXT: entry:
; IS__CGSCC_OPM-NEXT: call void @f(i32 noundef 0) [[ATTR7]]
; IS__CGSCC_OPM-NEXT: ret void
;
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@g
; IS__CGSCC_NPM-SAME: () [[ATTR0]] {
; IS__CGSCC_NPM-NEXT: entry:
; IS__CGSCC_NPM-NEXT: ret void
; ;
entry: entry:
call void @f(i32 0) call void @f(i32 0)
@ -279,7 +225,7 @@ define i32 @eval_func1(i32 (i32)* , i32) local_unnamed_addr {
define i32 @eval_func2(i32 (i32)* , i32) local_unnamed_addr null_pointer_is_valid{ define i32 @eval_func2(i32 (i32)* , i32) local_unnamed_addr null_pointer_is_valid{
; CHECK: Function Attrs: null_pointer_is_valid ; CHECK: Function Attrs: null_pointer_is_valid
; CHECK-LABEL: define {{[^@]+}}@eval_func2 ; CHECK-LABEL: define {{[^@]+}}@eval_func2
; CHECK-SAME: (i32 (i32)* nocapture nofree [[TMP0:%.*]], i32 [[TMP1:%.*]]) local_unnamed_addr [[ATTR6:#.*]] { ; CHECK-SAME: (i32 (i32)* nocapture nofree [[TMP0:%.*]], i32 [[TMP1:%.*]]) local_unnamed_addr [[ATTR9:#.*]] {
; CHECK-NEXT: [[TMP3:%.*]] = tail call i32 [[TMP0]](i32 [[TMP1]]) ; CHECK-NEXT: [[TMP3:%.*]] = tail call i32 [[TMP0]](i32 [[TMP1]])
; CHECK-NEXT: ret i32 [[TMP3]] ; CHECK-NEXT: ret i32 [[TMP3]]
; ;

View File

@ -600,7 +600,7 @@ define void @f1(i32){
; ;
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f1 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f1
; IS__CGSCC_OPM-SAME: (i32 [[TMP0:%.*]]) { ; IS__CGSCC_OPM-SAME: (i32 [[TMP0:%.*]]) {
; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = tail call i32 @r1(), [[RNG3:!range !.*]] ; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = tail call i32 @r1() [[ATTR4:#.*]], [[RNG3:!range !.*]]
; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15 ; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15
; IS__CGSCC_OPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]] ; IS__CGSCC_OPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]
; IS__CGSCC_OPM: 4: ; IS__CGSCC_OPM: 4:
@ -698,7 +698,7 @@ define dso_local i32 @test4-g1(i32 %u) {
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test4-g1 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test4-g1
; IS__CGSCC_OPM-SAME: (i32 [[U:%.*]]) [[ATTR2:#.*]] { ; IS__CGSCC_OPM-SAME: (i32 [[U:%.*]]) [[ATTR2:#.*]] {
; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: entry:
; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) [[ATTR4:#.*]] ; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) [[ATTR5:#.*]]
; IS__CGSCC_OPM-NEXT: ret i32 [[CALL]] ; IS__CGSCC_OPM-NEXT: ret i32 [[CALL]]
; ;
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
@ -790,7 +790,7 @@ define dso_local i32 @test4-g2(i32 %u) {
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test4-g2 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test4-g2
; IS__CGSCC_OPM-SAME: (i32 [[U:%.*]]) [[ATTR2]] { ; IS__CGSCC_OPM-SAME: (i32 [[U:%.*]]) [[ATTR2]] {
; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: entry:
; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) [[ATTR4]] ; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) [[ATTR5]]
; IS__CGSCC_OPM-NEXT: ret i32 [[CALL]] ; IS__CGSCC_OPM-NEXT: ret i32 [[CALL]]
; ;
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
@ -1154,10 +1154,10 @@ define i1 @fcmp_caller(float %fa, float %fb, double %da, double %db, double* %dp
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fcmp_caller ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fcmp_caller
; IS__CGSCC_OPM-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], double* nofree readnone [[DPA:%.*]], double* nofree readnone [[DPB:%.*]], i8* nofree readnone [[IPA:%.*]], i8* nofree readnone [[IPB:%.*]]) [[ATTR2]] { ; IS__CGSCC_OPM-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], double* nofree readnone [[DPA:%.*]], double* nofree readnone [[DPB:%.*]], i8* nofree readnone [[IPA:%.*]], i8* nofree readnone [[IPB:%.*]]) [[ATTR2]] {
; IS__CGSCC_OPM-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) [[ATTR4]] ; IS__CGSCC_OPM-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) [[ATTR5]]
; IS__CGSCC_OPM-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) [[ATTR4]] ; IS__CGSCC_OPM-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) [[ATTR5]]
; IS__CGSCC_OPM-NEXT: [[R3:%.*]] = call i1 @dp_icmp(double* noalias nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]]) [[ATTR4]] ; IS__CGSCC_OPM-NEXT: [[R3:%.*]] = call i1 @dp_icmp(double* noalias nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]]) [[ATTR5]]
; IS__CGSCC_OPM-NEXT: [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree readnone [[IPA]], i8* noalias nofree readnone [[IPB]]) [[ATTR4]] ; IS__CGSCC_OPM-NEXT: [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree readnone [[IPA]], i8* noalias nofree readnone [[IPB]]) [[ATTR5]]
; IS__CGSCC_OPM-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]] ; IS__CGSCC_OPM-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]]
; IS__CGSCC_OPM-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]] ; IS__CGSCC_OPM-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]]
; IS__CGSCC_OPM-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]] ; IS__CGSCC_OPM-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]]
@ -1329,8 +1329,8 @@ define i1 @callee_range_2(i1 %c1, i1 %c2) {
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@callee_range_2 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@callee_range_2
; IS__CGSCC_OPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) [[ATTR2]] { ; IS__CGSCC_OPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) [[ATTR2]] {
; IS__CGSCC_OPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) [[ATTR4]], [[RNG5:!range !.*]] ; IS__CGSCC_OPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) [[ATTR5]], [[RNG5:!range !.*]]
; IS__CGSCC_OPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) [[ATTR4]], [[RNG5]] ; IS__CGSCC_OPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) [[ATTR5]], [[RNG5]]
; IS__CGSCC_OPM-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]] ; IS__CGSCC_OPM-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]]
; IS__CGSCC_OPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3 ; IS__CGSCC_OPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3
; IS__CGSCC_OPM-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2 ; IS__CGSCC_OPM-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
@ -1488,10 +1488,10 @@ define i32 @simplify_callsite_argument(i1 %d) {
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false ; IS__CGSCC_OPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false
; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; IS__CGSCC_OPM: t: ; IS__CGSCC_OPM: t:
; IS__CGSCC_OPM-NEXT: [[RET1:%.*]] = call i32 @func(i1 noundef [[C]]) [[ATTR4]], [[RNG4:!range !.*]] ; IS__CGSCC_OPM-NEXT: [[RET1:%.*]] = call i32 @func(i1 noundef [[C]]) [[ATTR5]], [[RNG4:!range !.*]]
; IS__CGSCC_OPM-NEXT: ret i32 [[RET1]] ; IS__CGSCC_OPM-NEXT: ret i32 [[RET1]]
; IS__CGSCC_OPM: f: ; IS__CGSCC_OPM: f:
; IS__CGSCC_OPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 noundef false) [[ATTR4]], [[RNG4]] ; IS__CGSCC_OPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 noundef false) [[ATTR5]], [[RNG4]]
; IS__CGSCC_OPM-NEXT: ret i32 [[RET2]] ; IS__CGSCC_OPM-NEXT: ret i32 [[RET2]]
; ;
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
@ -1575,10 +1575,10 @@ define i1 @check_divided_range(i32 %arg) {
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@check_divided_range ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@check_divided_range
; IS__CGSCC_OPM-SAME: (i32 [[ARG:%.*]]) [[ATTR2]] { ; IS__CGSCC_OPM-SAME: (i32 [[ARG:%.*]]) [[ATTR2]] {
; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @less_than_65536(i32 noundef 0) [[ATTR4]] ; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @less_than_65536(i32 noundef 0) [[ATTR5]]
; IS__CGSCC_OPM-NEXT: [[CSRET2:%.*]] = call i32 @less_than_65536(i32 [[ARG]]) [[ATTR4]] ; IS__CGSCC_OPM-NEXT: [[CSRET2:%.*]] = call i32 @less_than_65536(i32 [[ARG]]) [[ATTR5]]
; IS__CGSCC_OPM-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET1]]) [[ATTR4]] ; IS__CGSCC_OPM-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET1]]) [[ATTR5]]
; IS__CGSCC_OPM-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET2]]) [[ATTR4]] ; IS__CGSCC_OPM-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET2]]) [[ATTR5]]
; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = and i1 [[TRUE1]], [[TRUE2]] ; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = and i1 [[TRUE1]], [[TRUE2]]
; IS__CGSCC_OPM-NEXT: ret i1 [[RET]] ; IS__CGSCC_OPM-NEXT: ret i1 [[RET]]
; ;
@ -1930,7 +1930,7 @@ define i1 @context(i8* %p) {
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = icmp slt i8 0, [[L]] ; IS__CGSCC_OPM-NEXT: [[C:%.*]] = icmp slt i8 0, [[L]]
; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; IS__CGSCC_OPM: t: ; IS__CGSCC_OPM: t:
; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call i1 @non_zero(i8 [[L]]) [[ATTR4]] ; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call i1 @non_zero(i8 [[L]]) [[ATTR5]]
; IS__CGSCC_OPM-NEXT: ret i1 [[R]] ; IS__CGSCC_OPM-NEXT: ret i1 [[R]]
; IS__CGSCC_OPM: f: ; IS__CGSCC_OPM: f:
; IS__CGSCC_OPM-NEXT: ret i1 false ; IS__CGSCC_OPM-NEXT: ret i1 false

View File

@ -204,7 +204,7 @@ define <4 x i32> @test11_2(<4 x i32*> %ptrs) {
; CHECK: Function Attrs: argmemonly nounwind readonly ; CHECK: Function Attrs: argmemonly nounwind readonly
; CHECK-LABEL: define {{[^@]+}}@test11_2 ; CHECK-LABEL: define {{[^@]+}}@test11_2
; CHECK-SAME: (<4 x i32*> [[PTRS:%.*]]) [[ATTR6:#.*]] { ; CHECK-SAME: (<4 x i32*> [[PTRS:%.*]]) [[ATTR6:#.*]] {
; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @test11_1(<4 x i32*> [[PTRS]]) [[ATTR2]] ; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @test11_1(<4 x i32*> [[PTRS]]) [[ATTR9:#.*]]
; CHECK-NEXT: ret <4 x i32> [[RES]] ; CHECK-NEXT: ret <4 x i32> [[RES]]
; ;
%res = call <4 x i32> @test11_1(<4 x i32*> %ptrs) %res = call <4 x i32> @test11_1(<4 x i32*> %ptrs)
@ -323,7 +323,7 @@ define void @byval_not_readonly_2(i8* byval(i8) %written) readonly {
define void @byval_not_readnone_1(i8* byval(i8) %written) readnone { define void @byval_not_readnone_1(i8* byval(i8) %written) readnone {
; CHECK: Function Attrs: readnone ; CHECK: Function Attrs: readnone
; CHECK-LABEL: define {{[^@]+}}@byval_not_readnone_1 ; CHECK-LABEL: define {{[^@]+}}@byval_not_readnone_1
; CHECK-SAME: (i8* noalias nonnull byval(i8) dereferenceable(1) [[WRITTEN:%.*]]) [[ATTR9:#.*]] { ; CHECK-SAME: (i8* noalias nonnull byval(i8) dereferenceable(1) [[WRITTEN:%.*]]) [[ATTR8:#.*]] {
; CHECK-NEXT: call void @escape_i8(i8* nonnull dereferenceable(1) [[WRITTEN]]) ; CHECK-NEXT: call void @escape_i8(i8* nonnull dereferenceable(1) [[WRITTEN]])
; CHECK-NEXT: ret void ; CHECK-NEXT: ret void
; ;
@ -395,7 +395,9 @@ declare void @val_use(i8 %ptr) readonly nounwind
define void @ptr_uses(i8* %ptr) { define void @ptr_uses(i8* %ptr) {
; CHECK: Function Attrs: nounwind readonly ; CHECK: Function Attrs: nounwind readonly
; CHECK-LABEL: define {{[^@]+}}@ptr_uses ; CHECK-LABEL: define {{[^@]+}}@ptr_uses
; CHECK-SAME: (i8* nocapture readonly [[PTR:%.*]]) [[ATTR10:#.*]] { ; CHECK-SAME: (i8* nocapture readonly [[PTR:%.*]]) [[ATTR9:#.*]] {
; CHECK-NEXT: [[CALL_PTR:%.*]] = call i8* @maybe_returned_ptr(i8* readonly [[PTR]])
; CHECK-NEXT: [[CALL_VAL:%.*]] = call i8 @maybe_returned_val(i8* readonly [[CALL_PTR]])
; CHECK-NEXT: ret void ; CHECK-NEXT: ret void
; ;
%call_ptr = call i8* @maybe_returned_ptr(i8* %ptr) %call_ptr = call i8* @maybe_returned_ptr(i8* %ptr)

View File

@ -392,6 +392,6 @@ entry:
ret i16 %cast ret i16 %cast
} }
attributes #0 = { nounwind readnone } attributes #0 = { nounwind readnone willreturn }
attributes #1 = { nounwind } attributes #1 = { nounwind }

View File

@ -21,7 +21,7 @@ entry:
if.end: if.end:
%gep = getelementptr i8, i8* %d, i32 42 %gep = getelementptr i8, i8* %d, i32 42
%call = call i64 @foo(i8* %gep) nounwind readonly %call = call i64 @foo(i8* %gep) nounwind readonly willreturn
%cmp2 = icmp ne i64 %call, 0 %cmp2 = icmp ne i64 %call, 0
call void @llvm.assume(i1 %cmp2) call void @llvm.assume(i1 %cmp2)
br label %exit br label %exit
@ -31,5 +31,5 @@ exit:
ret i32 %conv ret i32 %conv
} }
declare i64 @foo(i8*) nounwind readonly declare i64 @foo(i8*) nounwind readonly willreturn
declare void @llvm.assume(i1 noundef) nounwind willreturn declare void @llvm.assume(i1 noundef) nounwind willreturn

View File

@ -77,4 +77,4 @@ declare i1 @llvm.coro.end(i8*, i1)
declare noalias i8* @malloc(i32) declare noalias i8* @malloc(i32)
declare void @print(i32) declare void @print(i32)
declare void @free(i8*) declare void @free(i8*) willreturn

View File

@ -79,4 +79,4 @@ declare i1 @llvm.coro.end(i8*, i1)
declare noalias i8* @malloc(i32) declare noalias i8* @malloc(i32)
declare void @print(i32) declare void @print(i32)
declare void @free(i8*) declare void @free(i8*) willreturn

View File

@ -415,7 +415,7 @@ lpad:
} }
declare i8* @malloc(i32) declare i8* @malloc(i32)
declare void @free(i8*) declare void @free(i8*) willreturn
declare void @print(i32) declare void @print(i32)
declare void @foo() declare void @foo()

View File

@ -234,8 +234,8 @@ define i32 addrspace(1)* @test13_addrspacecast() {
} }
declare noalias i8* @malloc(i32) declare noalias i8* @malloc(i32) willreturn
declare noalias i8* @calloc(i32, i32) declare noalias i8* @calloc(i32, i32) willreturn
define void @test14(i32* %Q) { define void @test14(i32* %Q) {
; CHECK-LABEL: @test14( ; CHECK-LABEL: @test14(

View File

@ -1,8 +1,8 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -basic-aa -dse -enable-dse-memoryssa=false -S | FileCheck %s ; RUN: opt < %s -basic-aa -dse -enable-dse-memoryssa=false -S | FileCheck %s
declare i8* @_Znwj(i32) local_unnamed_addr declare i8* @_Znwj(i32) willreturn
declare void @foo() readnone declare void @foo() readnone willreturn
define void @test1(i8** %ptr) { define void @test1(i8** %ptr) {
; CHECK-LABEL: @test1( ; CHECK-LABEL: @test1(

View File

@ -267,8 +267,8 @@ define i32 addrspace(1)* @test13_addrspacecast() {
ret i32 addrspace(1)* %P ret i32 addrspace(1)* %P
} }
declare noalias i8* @malloc(i32) declare noalias i8* @malloc(i32) willreturn
declare noalias i8* @calloc(i32, i32) declare noalias i8* @calloc(i32, i32) willreturn
declare noalias i8* @aligned_alloc(i32, i32) declare noalias i8* @aligned_alloc(i32, i32)
declare void @free(i8*) declare void @free(i8*)

View File

@ -31,6 +31,10 @@ entry:
define void @caller_may_not_return() ssp { define void @caller_may_not_return() ssp {
; CHECK-LABEL: @caller_may_not_return( ; CHECK-LABEL: @caller_may_not_return(
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[WHILE_BODY_I:%.*]]
; CHECK: while.body.i:
; CHECK-NEXT: br label [[WHILE_BODY_I]]
; CHECK: readnone_may_not_return.exit:
; CHECK-NEXT: ret void ; CHECK-NEXT: ret void
; ;
entry: entry:
@ -41,13 +45,13 @@ entry:
; @caller_willreturn is marked as willreturn, so all called functions also must ; @caller_willreturn is marked as willreturn, so all called functions also must
; return. All calls are dead. ; return. All calls are dead.
define void @caller_willreturn() ssp willreturn { define void @caller_willreturn() ssp {
; CHECK-LABEL: @caller_willreturn( ; CHECK-LABEL: @caller_willreturn(
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: ret void ; CHECK-NEXT: ret void
; ;
entry: entry:
call void @readnone_may_not_return() call void @readnone_may_not_return() willreturn
call void @readnone_willreturn() call void @readnone_willreturn()
ret void ret void
} }

View File

@ -1,6 +1,6 @@
; RUN: opt < %s -instcombine -S | FileCheck %s ; RUN: opt < %s -instcombine -S | FileCheck %s
declare double @acos(double) declare double @acos(double) willreturn
; Check that functions without any function attributes are simplified. ; Check that functions without any function attributes are simplified.

View File

@ -1,6 +1,6 @@
; RUN: opt < %s -instcombine -S | not grep call ; RUN: opt < %s -instcombine -S | not grep call
; rdar://6880732 ; rdar://6880732
declare double @t1(i32) readonly declare double @t1(i32) readonly willreturn
define void @t2() nounwind { define void @t2() nounwind {
call double @t1(i32 42) ;; dead call even though callee is not nothrow. call double @t1(i32 42) ;; dead call even though callee is not nothrow.

View File

@ -2,13 +2,13 @@
; RUN: opt -S -early-cse -earlycse-debug-hash < %s | FileCheck %s ; RUN: opt -S -early-cse -earlycse-debug-hash < %s | FileCheck %s
declare float @nearbyintf(float) #0 declare float @nearbyintf(float) #0
declare float @llvm.nearbyint.f32(float) #0 declare float @llvm.nearbyint.f32(float)
declare double @nearbyint(double) #0 declare double @nearbyint(double) #0
declare double @llvm.nearbyint.f64(double) #0 declare double @llvm.nearbyint.f64(double)
declare float @rintf(float) #0 declare float @rintf(float) #0
declare float @llvm.rint.f32(float) #0 declare float @llvm.rint.f32(float)
declare double @rint(double) #0 declare double @rint(double) #0
declare double @llvm.rint.f64(double) #0 declare double @llvm.rint.f64(double)
define float @constant_fold_rint_f32_01() #0 { define float @constant_fold_rint_f32_01() #0 {
; CHECK-LABEL: @constant_fold_rint_f32_01( ; CHECK-LABEL: @constant_fold_rint_f32_01(
@ -106,4 +106,4 @@ define double @constant_fold_rint_f64_06() #0 {
ret double %x ret double %x
} }
attributes #0 = { nounwind readnone } attributes #0 = { nounwind readnone willreturn }

View File

@ -9,9 +9,9 @@
define internal void @func_1(i64* nocapture readnone %0) #0 { define internal void @func_1(i64* nocapture readnone %0) #0 {
; CHECK-LABEL: @func_1( ; CHECK-LABEL: @func_1(
; CHECK-NEXT: unreachable ; CHECK-NEXT: ret void
; ;
unreachable ret void
} }
define i16 @main(i16 %0, i16** nocapture readnone %1) #1 { define i16 @main(i16 %0, i16** nocapture readnone %1) #1 {
@ -24,5 +24,5 @@ bb1:
unreachable unreachable
} }
attributes #0 = { noinline norecurse nounwind readnone } attributes #0 = { noinline norecurse nounwind readnone willreturn }
attributes #1 = { norecurse nounwind readnone } attributes #1 = { norecurse nounwind readnone }

View File

@ -25,6 +25,6 @@ define i1 @gep3() {
; CHECK-NEXT: ret i1 false ; CHECK-NEXT: ret i1 false
} }
declare i8* @func1(i8* returned) nounwind readnone declare i8* @func1(i8* returned) nounwind readnone willreturn
declare %gept* @func2(%gept* returned) nounwind readnone declare %gept* @func2(%gept* returned) nounwind readnone willreturn

View File

@ -285,7 +285,7 @@ define void @test8() {
ret void ret void
} }
declare noalias i8* @malloc(i32) declare noalias i8* @malloc(i32) willreturn
; rdar://11341081 ; rdar://11341081
%struct.big = type { [50 x i32] } %struct.big = type { [50 x i32] }
@ -384,5 +384,6 @@ declare void @f2(%struct.big*)
; CHECK: attributes [[ATTR0]] = { nounwind } ; CHECK: attributes [[ATTR0]] = { nounwind }
; CHECK: attributes #1 = { argmemonly nofree nosync nounwind willreturn } ; CHECK: attributes #1 = { argmemonly nofree nosync nounwind willreturn }
; CHECK: attributes #2 = { nounwind ssp } ; CHECK: attributes #2 = { nounwind ssp }
; CHECK: attributes #3 = { nounwind ssp uwtable } ; CHECK: attributes #3 = { willreturn }
; CHECK: attributes #4 = { argmemonly nofree nosync nounwind willreturn writeonly } ; CHECK: attributes #4 = { nounwind ssp uwtable }
; CHECK: attributes #5 = { argmemonly nofree nosync nounwind willreturn writeonly }

View File

@ -14,4 +14,4 @@ entry:
ret void ret void
} }
attributes #1 = { noinline nounwind readnone } attributes #1 = { noinline nounwind readnone willreturn }

View File

@ -25,9 +25,9 @@ target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16
; ;
; We delete all but the first of the parallel regions in this test. ; We delete all but the first of the parallel regions in this test.
define void @delete_parallel_0() { define void @delete_parallel_0() {
; CHECK-LABEL: define {{[^@]+}}@delete_parallel_0() ; CHECK-LABEL: define {{[^@]+}}@delete_parallel_0() {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @0, i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined.willreturn to void (i32*, i32*, ...)*)) ; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0:@.*]], i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined.willreturn to void (i32*, i32*, ...)*))
; CHECK-NEXT: ret void ; CHECK-NEXT: ret void
; ;
entry: entry:
@ -40,9 +40,9 @@ entry:
define internal void @.omp_outlined.willreturn(i32* noalias %.global_tid., i32* noalias %.bound_tid.) { define internal void @.omp_outlined.willreturn(i32* noalias %.global_tid., i32* noalias %.bound_tid.) {
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #0 ; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) [[ATTR0:#.*]] {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: call void @unknown() #0 ; CHECK-NEXT: call void @unknown() [[ATTR0]]
; CHECK-NEXT: ret void ; CHECK-NEXT: ret void
; ;
entry: entry:
@ -52,9 +52,9 @@ entry:
define internal void @.omp_outlined.willreturn.0(i32* noalias %.global_tid., i32* noalias %.bound_tid.) willreturn { define internal void @.omp_outlined.willreturn.0(i32* noalias %.global_tid., i32* noalias %.bound_tid.) willreturn {
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.0 ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.0
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #1 ; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) [[ATTR1:#.*]] {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: call void @readonly() #4 ; CHECK-NEXT: call void @readonly() [[ATTR4:#.*]]
; CHECK-NEXT: ret void ; CHECK-NEXT: ret void
; ;
entry: entry:
@ -64,9 +64,9 @@ entry:
define internal void @.omp_outlined.willreturn.1(i32* noalias %.global_tid., i32* noalias %.bound_tid.) { define internal void @.omp_outlined.willreturn.1(i32* noalias %.global_tid., i32* noalias %.bound_tid.) {
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.1 ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.1
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #2 ; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) [[ATTR2:#.*]] {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: call void @readnone() #0 ; CHECK-NEXT: call void @readnone() [[ATTR0]]
; CHECK-NEXT: ret void ; CHECK-NEXT: ret void
; ;
entry: entry:
@ -76,7 +76,7 @@ entry:
define internal void @.omp_outlined.willreturn.2(i32* noalias %.global_tid., i32* noalias %.bound_tid.) { define internal void @.omp_outlined.willreturn.2(i32* noalias %.global_tid., i32* noalias %.bound_tid.) {
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.2 ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.2
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #3 ; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) [[ATTR3:#.*]] {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: ret void ; CHECK-NEXT: ret void
; ;
@ -97,11 +97,11 @@ entry:
; ;
; We delete only the last parallel regions in this test because the others might not return. ; We delete only the last parallel regions in this test because the others might not return.
define void @delete_parallel_1() { define void @delete_parallel_1() {
; CHECK-LABEL: define {{[^@]+}}@delete_parallel_1() ; CHECK-LABEL: define {{[^@]+}}@delete_parallel_1() {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @0, i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*)) ; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*))
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @0, i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined..0 to void (i32*, i32*, ...)*)) ; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined..0 to void (i32*, i32*, ...)*))
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @0, i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*)) ; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*))
; CHECK-NEXT: ret void ; CHECK-NEXT: ret void
; ;
entry: entry:
@ -114,7 +114,7 @@ entry:
define internal void @.omp_outlined.(i32* noalias %.global_tid., i32* noalias %.bound_tid.) { define internal void @.omp_outlined.(i32* noalias %.global_tid., i32* noalias %.bound_tid.) {
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined. ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) ; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: call void @unknown() ; CHECK-NEXT: call void @unknown()
; CHECK-NEXT: ret void ; CHECK-NEXT: ret void
@ -126,9 +126,9 @@ entry:
define internal void @.omp_outlined..0(i32* noalias %.global_tid., i32* noalias %.bound_tid.) { define internal void @.omp_outlined..0(i32* noalias %.global_tid., i32* noalias %.bound_tid.) {
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..0 ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..0
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #4 ; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) [[ATTR4]] {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: call void @readonly() #4 ; CHECK-NEXT: call void @readonly() [[ATTR4]]
; CHECK-NEXT: ret void ; CHECK-NEXT: ret void
; ;
entry: entry:
@ -138,7 +138,7 @@ entry:
define internal void @.omp_outlined..1(i32* noalias %.global_tid., i32* noalias %.bound_tid.) { define internal void @.omp_outlined..1(i32* noalias %.global_tid., i32* noalias %.bound_tid.) {
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..1 ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..1
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #5 ; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) [[ATTR5:#.*]] {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: call void @readnone() ; CHECK-NEXT: call void @readnone()
; CHECK-NEXT: ret void ; CHECK-NEXT: ret void
@ -150,7 +150,7 @@ entry:
define internal void @.omp_outlined..2(i32* noalias %.global_tid., i32* noalias %.bound_tid.) { define internal void @.omp_outlined..2(i32* noalias %.global_tid., i32* noalias %.bound_tid.) {
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..2 ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..2
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #3 ; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) [[ATTR3]] {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: ret void ; CHECK-NEXT: ret void
; ;
@ -184,16 +184,16 @@ entry:
; FIXME: We do not realize that `a` is dead and all accesses to it can be removed ; FIXME: We do not realize that `a` is dead and all accesses to it can be removed
; making the parallel regions readonly and deletable. ; making the parallel regions readonly and deletable.
define void @delete_parallel_2() { define void @delete_parallel_2() {
; CHECK-LABEL: define {{[^@]+}}@delete_parallel_2() ; CHECK-LABEL: define {{[^@]+}}@delete_parallel_2() {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[TMP:%.*]] = bitcast i32* [[A]] to i8* ; CHECK-NEXT: [[TMP:%.*]] = bitcast i32* [[A]] to i8*
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noundef nonnull align 4 dereferenceable(4) [[TMP]]) #0 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noundef nonnull align 4 dereferenceable(4) [[TMP]]) [[ATTR0]]
; CHECK-NEXT: store i32 0, i32* [[A]], align 4 ; CHECK-NEXT: store i32 0, i32* [[A]], align 4
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @0, i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..3 to void (i32*, i32*, ...)*), i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]]) ; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..3 to void (i32*, i32*, ...)*), i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]])
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @0, i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..4 to void (i32*, i32*, ...)*), i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A]]) ; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..4 to void (i32*, i32*, ...)*), i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A]])
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @0, i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..5 to void (i32*, i32*, ...)*), i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A]]) ; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..5 to void (i32*, i32*, ...)*), i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A]])
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @0, i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..6 to void (i32*, i32*, ...)*), i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A]]) ; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..6 to void (i32*, i32*, ...)*), i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A]])
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8* ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* noundef nonnull [[TMP1]]) ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* noundef nonnull [[TMP1]])
; CHECK-NEXT: ret void ; CHECK-NEXT: ret void
@ -214,9 +214,9 @@ entry:
define internal void @.omp_outlined..3(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %a) { define internal void @.omp_outlined..3(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %a) {
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..3 ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..3
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) #6 ; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) [[ATTR6:#.*]] {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: [[CALL:%.*]] = call i32 @omp_get_thread_num() #4 ; CHECK-NEXT: [[CALL:%.*]] = call i32 @omp_get_thread_num() [[ATTR12:#.*]]
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then: ; CHECK: if.then:
@ -244,17 +244,17 @@ if.end: ; preds = %if.then, %entry
define internal void @.omp_outlined..4(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %a) { define internal void @.omp_outlined..4(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %a) {
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..4 ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..4
; CHECK-SAME: (i32* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) ; CHECK-SAME: (i32* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 ; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(%struct.ident_t* noundef nonnull @0, i32 [[TMP]]) ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(%struct.ident_t* noundef nonnull [[GLOB0]], i32 [[TMP]])
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]] ; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]]
; CHECK: omp_if.then: ; CHECK: omp_if.then:
; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[A]], align 4 ; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[A]], align 4
; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP3]], 1 ; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP3]], 1
; CHECK-NEXT: store i32 [[INC]], i32* [[A]], align 4 ; CHECK-NEXT: store i32 [[INC]], i32* [[A]], align 4
; CHECK-NEXT: call void @__kmpc_end_master(%struct.ident_t* noundef nonnull @0, i32 [[TMP]]) ; CHECK-NEXT: call void @__kmpc_end_master(%struct.ident_t* noundef nonnull [[GLOB0]], i32 [[TMP]])
; CHECK-NEXT: br label [[OMP_IF_END]] ; CHECK-NEXT: br label [[OMP_IF_END]]
; CHECK: omp_if.end: ; CHECK: omp_if.end:
; CHECK-NEXT: ret void ; CHECK-NEXT: ret void
@ -286,21 +286,21 @@ declare void @__kmpc_end_master(%struct.ident_t*, i32)
define internal void @.omp_outlined..5(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %a) { define internal void @.omp_outlined..5(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %a) {
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..5 ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..5
; CHECK-SAME: (i32* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) ; CHECK-SAME: (i32* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* noundef nonnull @0) ; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* noundef nonnull [[GLOB0]]) [[ATTR12]]
; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 ; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_single(%struct.ident_t* noundef nonnull @0, i32 [[TMP]]) ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_single(%struct.ident_t* noundef nonnull [[GLOB0]], i32 [[TMP]])
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]] ; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]]
; CHECK: omp_if.then: ; CHECK: omp_if.then:
; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[A]], align 4 ; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[A]], align 4
; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP3]], 1 ; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP3]], 1
; CHECK-NEXT: store i32 [[INC]], i32* [[A]], align 4 ; CHECK-NEXT: store i32 [[INC]], i32* [[A]], align 4
; CHECK-NEXT: call void @__kmpc_end_single(%struct.ident_t* noundef nonnull @0, i32 [[TMP]]) ; CHECK-NEXT: call void @__kmpc_end_single(%struct.ident_t* noundef nonnull [[GLOB0]], i32 [[TMP]])
; CHECK-NEXT: br label [[OMP_IF_END]] ; CHECK-NEXT: br label [[OMP_IF_END]]
; CHECK: omp_if.end: ; CHECK: omp_if.end:
; CHECK-NEXT: call void @__kmpc_barrier(%struct.ident_t* noundef nonnull @1, i32 [[OMP_GLOBAL_THREAD_NUM]]) ; CHECK-NEXT: call void @__kmpc_barrier(%struct.ident_t* noundef nonnull [[GLOB1:@.*]], i32 [[OMP_GLOBAL_THREAD_NUM]])
; CHECK-NEXT: ret void ; CHECK-NEXT: ret void
; ;
entry: entry:
@ -324,18 +324,18 @@ omp_if.end: ; preds = %entry, %omp_if.then
define internal void @.omp_outlined..6(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %a) { define internal void @.omp_outlined..6(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %a) {
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..6 ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..6
; CHECK-SAME: (i32* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) ; CHECK-SAME: (i32* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: [[A1:%.*]] = alloca i32, align 4 ; CHECK-NEXT: [[A1:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8 ; CHECK-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
; CHECK-NEXT: [[TMP:%.*]] = bitcast i32* [[A1]] to i8* ; CHECK-NEXT: [[TMP:%.*]] = bitcast i32* [[A1]] to i8*
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noundef nonnull align 4 [[TMP]]) #0 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noundef nonnull align 4 [[TMP]]) [[ATTR0]]
; CHECK-NEXT: store i32 1, i32* [[A1]], align 4 ; CHECK-NEXT: store i32 1, i32* [[A1]], align 4
; CHECK-NEXT: [[TMP1:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i32** ; CHECK-NEXT: [[TMP1:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i32**
; CHECK-NEXT: store i32* [[A1]], i32** [[TMP1]], align 8 ; CHECK-NEXT: store i32* [[A1]], i32** [[TMP1]], align 8
; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4 ; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4
; CHECK-NEXT: [[TMP3:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8* ; CHECK-NEXT: [[TMP3:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
; CHECK-NEXT: [[TMP4:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* noundef nonnull @2, i32 [[TMP2]], i32 noundef 1, i64 noundef 8, i8* noundef nonnull align 8 [[TMP3]], void (i8*, i8*)* noundef nonnull @.omp.reduction.reduction_func, [8 x i32]* noundef nonnull @.gomp_critical_user_.reduction.var) ; CHECK-NEXT: [[TMP4:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* noundef nonnull [[GLOB2:@.*]], i32 [[TMP2]], i32 noundef 1, i64 noundef 8, i8* noundef nonnull align 8 [[TMP3]], void (i8*, i8*)* noundef nonnull @.omp.reduction.reduction_func, [8 x i32]* noundef nonnull @.gomp_critical_user_.reduction.var)
; CHECK-NEXT: switch i32 [[TMP4]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [ ; CHECK-NEXT: switch i32 [[TMP4]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
; CHECK-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]] ; CHECK-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
; CHECK-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]] ; CHECK-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
@ -345,7 +345,7 @@ define internal void @.omp_outlined..6(i32* noalias %.global_tid., i32* noalias
; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* [[A1]], align 4 ; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* [[A1]], align 4
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP6]] ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP6]]
; CHECK-NEXT: store i32 [[ADD]], i32* [[A]], align 4 ; CHECK-NEXT: store i32 [[ADD]], i32* [[A]], align 4
; CHECK-NEXT: call void @__kmpc_end_reduce_nowait(%struct.ident_t* noundef nonnull @2, i32 [[TMP2]], [8 x i32]* noundef nonnull @.gomp_critical_user_.reduction.var) ; CHECK-NEXT: call void @__kmpc_end_reduce_nowait(%struct.ident_t* noundef nonnull [[GLOB2]], i32 [[TMP2]], [8 x i32]* noundef nonnull @.gomp_critical_user_.reduction.var)
; CHECK-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]] ; CHECK-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
; CHECK: .omp.reduction.case2: ; CHECK: .omp.reduction.case2:
; CHECK-NEXT: [[TMP7:%.*]] = load i32, i32* [[A1]], align 4 ; CHECK-NEXT: [[TMP7:%.*]] = load i32, i32* [[A1]], align 4
@ -393,7 +393,7 @@ entry:
define internal void @.omp.reduction.reduction_func(i8* %arg, i8* %arg1) { define internal void @.omp.reduction.reduction_func(i8* %arg, i8* %arg1) {
; CHECK-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func ; CHECK-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func
; CHECK-SAME: (i8* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[ARG:%.*]], i8* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[ARG1:%.*]]) #{{[0-9]+}} ; CHECK-SAME: (i8* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[ARG:%.*]], i8* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[ARG1:%.*]]) [[ATTR9:#.*]] {
; CHECK-NEXT: entry: ; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP:%.*]] = bitcast i8* [[ARG1]] to i32** ; CHECK-NEXT: [[TMP:%.*]] = bitcast i8* [[ARG1]] to i32**
; CHECK-NEXT: [[TMP2:%.*]] = load i32*, i32** [[TMP]], align 8 ; CHECK-NEXT: [[TMP2:%.*]] = load i32*, i32** [[TMP]], align 8

View File

@ -20,7 +20,7 @@ entry:
ret void ret void
} }
define internal void @bar() noinline nounwind readnone { define internal void @bar() noinline nounwind readnone willreturn {
entry: entry:
ret void ret void
} }