; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals ; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=14 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=14 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM ; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM target datalayout = "e-m:e-i54:64-f80:128-n8:16:32:64-S128" ; Test cases specifically designed for the "willreturn" function attribute. ; We use FIXME's to indicate problems and missing attributes. ; TEST 1 (positive case) define void @only_return() #0 { ; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable ; CHECK-LABEL: define {{[^@]+}}@only_return ; CHECK-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: ret void ; ret void } ; TEST 2 (positive & negative case) ; 2.1 (positive case) ; recursive function which will halt ; int fib(int n){ ; return n<=1? n : fib(n-1) + fib(n-2); ; } ; FIXME: missing willreturn define i32 @fib(i32 %0) local_unnamed_addr #0 { ; IS__TUNIT_OPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fib ; IS__TUNIT_OPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { ; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 2 ; IS__TUNIT_OPM-NEXT: br i1 [[TMP2]], label [[TMP9:%.*]], label [[TMP3:%.*]] ; IS__TUNIT_OPM: 3: ; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = add nsw i32 [[TMP0]], -1 ; IS__TUNIT_OPM-NEXT: [[TMP5:%.*]] = tail call i32 @fib(i32 [[TMP4]]) #[[ATTR24:[0-9]+]] ; IS__TUNIT_OPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], -2 ; IS__TUNIT_OPM-NEXT: [[TMP7:%.*]] = tail call i32 @fib(i32 [[TMP6]]) #[[ATTR24]] ; IS__TUNIT_OPM-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], [[TMP5]] ; IS__TUNIT_OPM-NEXT: ret i32 [[TMP8]] ; IS__TUNIT_OPM: 9: ; IS__TUNIT_OPM-NEXT: ret i32 [[TMP0]] ; ; IS__TUNIT_NPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fib ; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { ; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 2 ; IS__TUNIT_NPM-NEXT: br i1 [[TMP2]], label [[TMP9:%.*]], label [[TMP3:%.*]] ; IS__TUNIT_NPM: 3: ; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = add nsw i32 [[TMP0]], -1 ; IS__TUNIT_NPM-NEXT: [[TMP5:%.*]] = tail call i32 @fib(i32 [[TMP4]]) #[[ATTR26:[0-9]+]] ; IS__TUNIT_NPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], -2 ; IS__TUNIT_NPM-NEXT: [[TMP7:%.*]] = tail call i32 @fib(i32 [[TMP6]]) #[[ATTR26]] ; IS__TUNIT_NPM-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], [[TMP5]] ; IS__TUNIT_NPM-NEXT: ret i32 [[TMP8]] ; IS__TUNIT_NPM: 9: ; IS__TUNIT_NPM-NEXT: ret i32 [[TMP0]] ; ; IS__CGSCC_OPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fib ; IS__CGSCC_OPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 2 ; IS__CGSCC_OPM-NEXT: br i1 [[TMP2]], label [[TMP9:%.*]], label [[TMP3:%.*]] ; IS__CGSCC_OPM: 3: ; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = add nsw i32 [[TMP0]], -1 ; IS__CGSCC_OPM-NEXT: [[TMP5:%.*]] = tail call i32 @fib(i32 [[TMP4]]) #[[ATTR17:[0-9]+]] ; IS__CGSCC_OPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], -2 ; IS__CGSCC_OPM-NEXT: [[TMP7:%.*]] = tail call i32 @fib(i32 [[TMP6]]) #[[ATTR17]] ; IS__CGSCC_OPM-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], [[TMP5]] ; IS__CGSCC_OPM-NEXT: ret i32 [[TMP8]] ; IS__CGSCC_OPM: 9: ; IS__CGSCC_OPM-NEXT: ret i32 [[TMP0]] ; ; IS__CGSCC_NPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fib ; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 2 ; IS__CGSCC_NPM-NEXT: br i1 [[TMP2]], label [[TMP9:%.*]], label [[TMP3:%.*]] ; IS__CGSCC_NPM: 3: ; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = add nsw i32 [[TMP0]], -1 ; IS__CGSCC_NPM-NEXT: [[TMP5:%.*]] = tail call i32 @fib(i32 [[TMP4]]) #[[ATTR19:[0-9]+]] ; IS__CGSCC_NPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], -2 ; IS__CGSCC_NPM-NEXT: [[TMP7:%.*]] = tail call i32 @fib(i32 [[TMP6]]) #[[ATTR19]] ; IS__CGSCC_NPM-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], [[TMP5]] ; IS__CGSCC_NPM-NEXT: ret i32 [[TMP8]] ; IS__CGSCC_NPM: 9: ; IS__CGSCC_NPM-NEXT: ret i32 [[TMP0]] ; %2 = icmp slt i32 %0, 2 br i1 %2, label %9, label %3 ; <label>:3: ; preds = %1 %4 = add nsw i32 %0, -1 %5 = tail call i32 @fib(i32 %4) %6 = add nsw i32 %0, -2 %7 = tail call i32 @fib(i32 %6) %8 = add nsw i32 %7, %5 ret i32 %8 ; <label>:9: ; preds = %1 ret i32 %0 } ; 2.2 (negative case) ; recursive function which doesn't stop for some input. ; int fact_maybe_not_halt(int n) { ; if (n==0) { ; return 1; ; } ; return fact_maybe_not_halt( n > 0 ? n-1 : n) * n; ; } ; fact_maybe_not(-1) doesn't stop. define i32 @fact_maybe_not_halt(i32 %0) local_unnamed_addr #0 { ; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable ; CHECK-LABEL: define {{[^@]+}}@fact_maybe_not_halt ; CHECK-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 0 ; CHECK-NEXT: br i1 [[TMP2]], label [[TMP11:%.*]], label [[TMP3:%.*]] ; CHECK: 3: ; CHECK-NEXT: [[TMP4:%.*]] = phi i32 [ [[TMP8:%.*]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ] ; CHECK-NEXT: [[TMP5:%.*]] = phi i32 [ [[TMP9:%.*]], [[TMP3]] ], [ 1, [[TMP1]] ] ; CHECK-NEXT: [[TMP6:%.*]] = icmp sgt i32 [[TMP4]], 0 ; CHECK-NEXT: [[TMP7:%.*]] = sext i1 [[TMP6]] to i32 ; CHECK-NEXT: [[TMP8]] = add nsw i32 [[TMP4]], [[TMP7]] ; CHECK-NEXT: [[TMP9]] = mul nsw i32 [[TMP4]], [[TMP5]] ; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP8]], 0 ; CHECK-NEXT: br i1 [[TMP10]], label [[TMP11]], label [[TMP3]] ; CHECK: 11: ; CHECK-NEXT: [[TMP12:%.*]] = phi i32 [ 1, [[TMP1]] ], [ [[TMP9]], [[TMP3]] ] ; CHECK-NEXT: ret i32 [[TMP12]] ; %2 = icmp eq i32 %0, 0 br i1 %2, label %11, label %3 ; <label>:3: ; preds = %1, %3 %4 = phi i32 [ %8, %3 ], [ %0, %1 ] %5 = phi i32 [ %9, %3 ], [ 1, %1 ] %6 = icmp sgt i32 %4, 0 %7 = sext i1 %6 to i32 %8 = add nsw i32 %4, %7 %9 = mul nsw i32 %4, %5 %10 = icmp eq i32 %8, 0 br i1 %10, label %11, label %3 ; <label>:11: ; preds = %3, %1 %12 = phi i32 [ 1, %1 ], [ %9, %3 ] ret i32 %12 } ; TEST 3 (positive case) ; loop ; int fact_loop(int n ){ ; int ans = 1; ; for(int i = 1;i<=n;i++){ ; ans *= i; ; } ; return ans; ; } define i32 @fact_loop(i32 %0) local_unnamed_addr #0 { ; IS________OPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable ; IS________OPM-LABEL: define {{[^@]+}}@fact_loop ; IS________OPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] { ; IS________OPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 1 ; IS________OPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] ; IS________OPM: 3: ; IS________OPM-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[TMP1:%.*]] ], [ [[TMP8:%.*]], [[TMP5]] ] ; IS________OPM-NEXT: ret i32 [[TMP4]] ; IS________OPM: 5: ; IS________OPM-NEXT: [[TMP6:%.*]] = phi i32 [ [[TMP9:%.*]], [[TMP5]] ], [ 1, [[TMP1]] ] ; IS________OPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8]], [[TMP5]] ], [ 1, [[TMP1]] ] ; IS________OPM-NEXT: [[TMP8]] = mul nsw i32 [[TMP6]], [[TMP7]] ; IS________OPM-NEXT: [[TMP9]] = add nuw nsw i32 [[TMP6]], 1 ; IS________OPM-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP6]], [[TMP0]] ; IS________OPM-NEXT: br i1 [[TMP10]], label [[TMP3]], label [[TMP5]] ; ; IS________NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable ; IS________NPM-LABEL: define {{[^@]+}}@fact_loop ; IS________NPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] { ; IS________NPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 1 ; IS________NPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] ; IS________NPM: 3: ; IS________NPM-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[TMP1:%.*]] ], [ [[TMP8:%.*]], [[TMP5]] ] ; IS________NPM-NEXT: ret i32 [[TMP4]] ; IS________NPM: 5: ; IS________NPM-NEXT: [[TMP6:%.*]] = phi i32 [ [[TMP9:%.*]], [[TMP5]] ], [ 1, [[TMP1]] ] ; IS________NPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8]], [[TMP5]] ], [ 1, [[TMP1]] ] ; IS________NPM-NEXT: [[TMP8]] = mul nsw i32 [[TMP6]], [[TMP7]] ; IS________NPM-NEXT: [[TMP9]] = add nuw nsw i32 [[TMP6]], 1 ; IS________NPM-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP6]], [[TMP0]] ; IS________NPM-NEXT: br i1 [[TMP10]], label [[TMP3]], label [[TMP5]] ; %2 = icmp slt i32 %0, 1 br i1 %2, label %3, label %5 ; <label>:3: ; preds = %5, %1 %4 = phi i32 [ 1, %1 ], [ %8, %5 ] ret i32 %4 ; <label>:5: ; preds = %1, %5 %6 = phi i32 [ %9, %5 ], [ 1, %1 ] %7 = phi i32 [ %8, %5 ], [ 1, %1 ] %8 = mul nsw i32 %6, %7 %9 = add nuw nsw i32 %6, 1 %10 = icmp eq i32 %6, %0 br i1 %10, label %3, label %5 } ; TEST 4 (negative case) ; mutual recursion ; void mutual_recursion1(){ ; mutual_recursion2(); ; } ; void mutual_recursion2(){ ; mutual_recursion1(); ; } declare void @sink() nounwind willreturn nosync nofree define void @mutual_recursion1(i1 %c) #0 { ; IS________OPM: Function Attrs: nofree noinline nosync nounwind uwtable ; IS________OPM-LABEL: define {{[^@]+}}@mutual_recursion1 ; IS________OPM-SAME: (i1 [[C:%.*]]) #[[ATTR4:[0-9]+]] { ; IS________OPM-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]] ; IS________OPM: rec: ; IS________OPM-NEXT: call void @sink() #[[ATTR12:[0-9]+]] ; IS________OPM-NEXT: call void @mutual_recursion2(i1 [[C]]) #[[ATTR25:[0-9]+]] ; IS________OPM-NEXT: br label [[END]] ; IS________OPM: end: ; IS________OPM-NEXT: ret void ; ; IS________NPM: Function Attrs: nofree noinline nosync nounwind uwtable ; IS________NPM-LABEL: define {{[^@]+}}@mutual_recursion1 ; IS________NPM-SAME: (i1 [[C:%.*]]) #[[ATTR4:[0-9]+]] { ; IS________NPM-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]] ; IS________NPM: rec: ; IS________NPM-NEXT: call void @sink() #[[ATTR12:[0-9]+]] ; IS________NPM-NEXT: call void @mutual_recursion2(i1 noundef [[C]]) #[[ATTR27:[0-9]+]] ; IS________NPM-NEXT: br label [[END]] ; IS________NPM: end: ; IS________NPM-NEXT: ret void ; br i1 %c, label %rec, label %end rec: call void @sink() call void @mutual_recursion2(i1 %c) br label %end end: ret void } define void @mutual_recursion2(i1 %c) #0 { ; IS________OPM: Function Attrs: nofree noinline nosync nounwind uwtable ; IS________OPM-LABEL: define {{[^@]+}}@mutual_recursion2 ; IS________OPM-SAME: (i1 [[C:%.*]]) #[[ATTR4]] { ; IS________OPM-NEXT: call void @mutual_recursion1(i1 [[C]]) #[[ATTR25]] ; IS________OPM-NEXT: ret void ; ; IS________NPM: Function Attrs: nofree noinline nosync nounwind uwtable ; IS________NPM-LABEL: define {{[^@]+}}@mutual_recursion2 ; IS________NPM-SAME: (i1 [[C:%.*]]) #[[ATTR4]] { ; IS________NPM-NEXT: call void @mutual_recursion1(i1 [[C]]) #[[ATTR27]] ; IS________NPM-NEXT: ret void ; call void @mutual_recursion1(i1 %c) ret void } ; TEST 5 (negative case) ; call exit/abort (has noreturn attribute) ; CHECK: Function Attrs: noreturn ; CHECK-NEXT: declare void @exit(i32) local_unnamed_add declare void @exit(i32 %0) local_unnamed_addr noreturn define void @only_exit() local_unnamed_addr #0 { ; CHECK: Function Attrs: noinline noreturn nounwind uwtable ; CHECK-LABEL: define {{[^@]+}}@only_exit ; CHECK-SAME: () local_unnamed_addr #[[ATTR6:[0-9]+]] { ; CHECK-NEXT: tail call void @exit(i32 noundef 0) #[[ATTR5:[0-9]+]] ; CHECK-NEXT: unreachable ; tail call void @exit(i32 0) unreachable } ; conditional exit ; void conditional_exit(int cond, int *p){ ; if(cond){ ; exit(0); ; } ; if(*p){ ; exit(1); ; } ; return; ; } define void @conditional_exit(i32 %0, i32* nocapture readonly %1) local_unnamed_addr #0 { ; CHECK: Function Attrs: noinline nounwind uwtable ; CHECK-LABEL: define {{[^@]+}}@conditional_exit ; CHECK-SAME: (i32 [[TMP0:%.*]], i32* nocapture nofree readonly [[TMP1:%.*]]) local_unnamed_addr #[[ATTR7:[0-9]+]] { ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 ; CHECK-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]] ; CHECK: 4: ; CHECK-NEXT: tail call void @exit(i32 noundef 0) #[[ATTR5]] ; CHECK-NEXT: unreachable ; CHECK: 5: ; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* [[TMP1]], align 4 ; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 0 ; CHECK-NEXT: br i1 [[TMP7]], label [[TMP9:%.*]], label [[TMP8:%.*]] ; CHECK: 8: ; CHECK-NEXT: tail call void @exit(i32 noundef 1) #[[ATTR5]] ; CHECK-NEXT: unreachable ; CHECK: 9: ; CHECK-NEXT: ret void ; %3 = icmp eq i32 %0, 0 br i1 %3, label %5, label %4 ; <label>:4: ; preds = %2 tail call void @exit(i32 0) unreachable ; <label>:5: ; preds = %2 %6 = load i32, i32* %1, align 4 %7 = icmp eq i32 %6, 0 br i1 %7, label %9, label %8 ; <label>:8: ; preds = %5 tail call void @exit(i32 1) unreachable ; <label>:9: ; preds = %5 ret void } ; TEST 6 (positive case) ; Call intrinsic function ; CHECK: Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn ; CHECK-NEXT: declare float @llvm.floor.f32(float) declare float @llvm.floor.f32(float) define void @call_floor(float %a) #0 { ; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable ; CHECK-LABEL: define {{[^@]+}}@call_floor ; CHECK-SAME: (float [[A:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: ret void ; tail call float @llvm.floor.f32(float %a) ret void } define float @call_floor2(float %a) #0 { ; IS________OPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable ; IS________OPM-LABEL: define {{[^@]+}}@call_floor2 ; IS________OPM-SAME: (float [[A:%.*]]) #[[ATTR0]] { ; IS________OPM-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]]) #[[ATTR26:[0-9]+]] ; IS________OPM-NEXT: ret float [[C]] ; ; IS________NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable ; IS________NPM-LABEL: define {{[^@]+}}@call_floor2 ; IS________NPM-SAME: (float [[A:%.*]]) #[[ATTR0]] { ; IS________NPM-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]]) #[[ATTR28:[0-9]+]] ; IS________NPM-NEXT: ret float [[C]] ; %c = tail call float @llvm.floor.f32(float %a) ret float %c } ; TEST 7 (negative case) ; Call function declaration without willreturn ; CHECK: Function Attrs: noinline nounwind uwtable ; CHECK-NOT: willreturn ; CHECK-NEXT: declare void @maybe_noreturn() declare void @maybe_noreturn() #0 define void @call_maybe_noreturn() #0 { ; IS________OPM: Function Attrs: noinline nounwind uwtable ; IS________OPM-LABEL: define {{[^@]+}}@call_maybe_noreturn ; IS________OPM-SAME: () #[[ATTR7]] { ; IS________OPM-NEXT: tail call void @maybe_noreturn() #[[ATTR27:[0-9]+]] ; IS________OPM-NEXT: ret void ; ; IS________NPM: Function Attrs: noinline nounwind uwtable ; IS________NPM-LABEL: define {{[^@]+}}@call_maybe_noreturn ; IS________NPM-SAME: () #[[ATTR7]] { ; IS________NPM-NEXT: tail call void @maybe_noreturn() #[[ATTR29:[0-9]+]] ; IS________NPM-NEXT: ret void ; tail call void @maybe_noreturn() ret void } ; TEST 8 (positive case) ; Check propagation. ; CHECK: Function Attrs: norecurse willreturn ; CHECK-NEXT: declare void @will_return() declare void @will_return() willreturn norecurse define void @f1() #0 { ; IS________OPM: Function Attrs: noinline nounwind willreturn uwtable ; IS________OPM-LABEL: define {{[^@]+}}@f1 ; IS________OPM-SAME: () #[[ATTR10:[0-9]+]] { ; IS________OPM-NEXT: tail call void @will_return() #[[ATTR28:[0-9]+]] ; IS________OPM-NEXT: ret void ; ; IS________NPM: Function Attrs: noinline nounwind willreturn uwtable ; IS________NPM-LABEL: define {{[^@]+}}@f1 ; IS________NPM-SAME: () #[[ATTR10:[0-9]+]] { ; IS________NPM-NEXT: tail call void @will_return() #[[ATTR30:[0-9]+]] ; IS________NPM-NEXT: ret void ; tail call void @will_return() ret void } define void @f2() #0 { ; CHECK: Function Attrs: noinline nounwind willreturn uwtable ; CHECK-LABEL: define {{[^@]+}}@f2 ; CHECK-SAME: () #[[ATTR10:[0-9]+]] { ; CHECK-NEXT: tail call void @f1() #[[ATTR12:[0-9]+]] ; CHECK-NEXT: ret void ; tail call void @f1() ret void } ; TEST 9 (negative case) ; call willreturn function in endless loop. define void @call_will_return_but_has_loop() #0 { ; CHECK: Function Attrs: noinline noreturn nounwind uwtable ; CHECK-LABEL: define {{[^@]+}}@call_will_return_but_has_loop ; CHECK-SAME: () #[[ATTR6]] { ; CHECK-NEXT: br label [[LABEL1:%.*]] ; CHECK: label1: ; CHECK-NEXT: tail call void @will_return() ; CHECK-NEXT: br label [[LABEL2:%.*]] ; CHECK: label2: ; CHECK-NEXT: br label [[LABEL1]] ; br label %label1 label1: tail call void @will_return() br label %label2 label2: br label %label1 } ; TEST 10 (positive case) ; invoke a function with willreturn ; CHECK: Function Attrs: noinline willreturn uwtable ; CHECK-NEXT: declare i1 @maybe_raise_exception() declare i1 @maybe_raise_exception() #1 willreturn define void @invoke_test() personality i32 (...)* @__gxx_personality_v0 { ; IS________OPM: Function Attrs: nounwind willreturn ; IS________OPM-LABEL: define {{[^@]+}}@invoke_test ; IS________OPM-SAME: () #[[ATTR12]] personality i32 (...)* @__gxx_personality_v0 { ; IS________OPM-NEXT: [[TMP1:%.*]] = invoke i1 @maybe_raise_exception() #[[ATTR28]] ; IS________OPM-NEXT: to label [[N:%.*]] unwind label [[F:%.*]] ; IS________OPM: N: ; IS________OPM-NEXT: ret void ; IS________OPM: F: ; IS________OPM-NEXT: [[VAL:%.*]] = landingpad { i8*, i32 } ; IS________OPM-NEXT: catch i8* null ; IS________OPM-NEXT: ret void ; ; IS________NPM: Function Attrs: nounwind willreturn ; IS________NPM-LABEL: define {{[^@]+}}@invoke_test ; IS________NPM-SAME: () #[[ATTR12]] personality i32 (...)* @__gxx_personality_v0 { ; IS________NPM-NEXT: [[TMP1:%.*]] = invoke i1 @maybe_raise_exception() #[[ATTR30]] ; IS________NPM-NEXT: to label [[N:%.*]] unwind label [[F:%.*]] ; IS________NPM: N: ; IS________NPM-NEXT: ret void ; IS________NPM: F: ; IS________NPM-NEXT: [[VAL:%.*]] = landingpad { i8*, i32 } ; IS________NPM-NEXT: catch i8* null ; IS________NPM-NEXT: ret void ; invoke i1 @maybe_raise_exception() to label %N unwind label %F N: ret void F: %val = landingpad { i8*, i32 } catch i8* null ret void } declare i32 @__gxx_personality_v0(...) ; TEST 11 (positive case) ; constant trip count ; int loop_constant_trip_count(int*p){ ; int ans = 0; ; for(int i = 0;i<10;i++){ ; ans += p[i]; ; } ; return ans; ; } define i32 @loop_constant_trip_count(i32* nocapture readonly %0) #0 { ; IS________OPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable ; IS________OPM-LABEL: define {{[^@]+}}@loop_constant_trip_count ; IS________OPM-SAME: (i32* nocapture nofree readonly [[TMP0:%.*]]) #[[ATTR13:[0-9]+]] { ; IS________OPM-NEXT: br label [[TMP3:%.*]] ; IS________OPM: 2: ; IS________OPM-NEXT: ret i32 [[TMP8:%.*]] ; IS________OPM: 3: ; IS________OPM-NEXT: [[TMP4:%.*]] = phi i64 [ 0, [[TMP1:%.*]] ], [ [[TMP9:%.*]], [[TMP3]] ] ; IS________OPM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP1]] ], [ [[TMP8]], [[TMP3]] ] ; IS________OPM-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP4]] ; IS________OPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP6]], align 4 ; IS________OPM-NEXT: [[TMP8]] = add nsw i32 [[TMP7]], [[TMP5]] ; IS________OPM-NEXT: [[TMP9]] = add nuw nsw i64 [[TMP4]], 1 ; IS________OPM-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 10 ; IS________OPM-NEXT: br i1 [[TMP10]], label [[TMP2:%.*]], label [[TMP3]] ; ; IS________NPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable ; IS________NPM-LABEL: define {{[^@]+}}@loop_constant_trip_count ; IS________NPM-SAME: (i32* nocapture nofree nonnull readonly dereferenceable(4) [[TMP0:%.*]]) #[[ATTR13:[0-9]+]] { ; IS________NPM-NEXT: br label [[TMP3:%.*]] ; IS________NPM: 2: ; IS________NPM-NEXT: ret i32 [[TMP8:%.*]] ; IS________NPM: 3: ; IS________NPM-NEXT: [[TMP4:%.*]] = phi i64 [ 0, [[TMP1:%.*]] ], [ [[TMP9:%.*]], [[TMP3]] ] ; IS________NPM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP1]] ], [ [[TMP8]], [[TMP3]] ] ; IS________NPM-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP4]] ; IS________NPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP6]], align 4 ; IS________NPM-NEXT: [[TMP8]] = add nsw i32 [[TMP7]], [[TMP5]] ; IS________NPM-NEXT: [[TMP9]] = add nuw nsw i64 [[TMP4]], 1 ; IS________NPM-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 10 ; IS________NPM-NEXT: br i1 [[TMP10]], label [[TMP2:%.*]], label [[TMP3]] ; br label %3 ; <label>:2: ; preds = %3 ret i32 %8 ; <label>:3: ; preds = %3, %1 %4 = phi i64 [ 0, %1 ], [ %9, %3 ] %5 = phi i32 [ 0, %1 ], [ %8, %3 ] %6 = getelementptr inbounds i32, i32* %0, i64 %4 %7 = load i32, i32* %6, align 4 %8 = add nsw i32 %7, %5 %9 = add nuw nsw i64 %4, 1 %10 = icmp eq i64 %9, 10 br i1 %10, label %2, label %3 } ; TEST 12 (negative case) ; unbounded trip count ; int loop_trip_count_unbound(unsigned s,unsigned e, int *p, int offset){ ; int ans = 0; ; for(unsigned i = s;i != e;i+=offset){ ; ans += p[i]; ; } ; return ans; ; } define i32 @loop_trip_count_unbound(i32 %0, i32 %1, i32* nocapture readonly %2, i32 %3) local_unnamed_addr #0 { ; IS________OPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable ; IS________OPM-LABEL: define {{[^@]+}}@loop_trip_count_unbound ; IS________OPM-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]], i32* nocapture nofree readonly [[TMP2:%.*]], i32 [[TMP3:%.*]]) local_unnamed_addr #[[ATTR13]] { ; IS________OPM-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]] ; IS________OPM-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP8:%.*]] ; IS________OPM: 6: ; IS________OPM-NEXT: [[TMP7:%.*]] = phi i32 [ 0, [[TMP4:%.*]] ], [ [[TMP14:%.*]], [[TMP8]] ] ; IS________OPM-NEXT: ret i32 [[TMP7]] ; IS________OPM: 8: ; IS________OPM-NEXT: [[TMP9:%.*]] = phi i32 [ [[TMP15:%.*]], [[TMP8]] ], [ [[TMP0]], [[TMP4]] ] ; IS________OPM-NEXT: [[TMP10:%.*]] = phi i32 [ [[TMP14]], [[TMP8]] ], [ 0, [[TMP4]] ] ; IS________OPM-NEXT: [[TMP11:%.*]] = zext i32 [[TMP9]] to i64 ; IS________OPM-NEXT: [[TMP12:%.*]] = getelementptr inbounds i32, i32* [[TMP2]], i64 [[TMP11]] ; IS________OPM-NEXT: [[TMP13:%.*]] = load i32, i32* [[TMP12]], align 4 ; IS________OPM-NEXT: [[TMP14]] = add nsw i32 [[TMP13]], [[TMP10]] ; IS________OPM-NEXT: [[TMP15]] = add i32 [[TMP9]], [[TMP3]] ; IS________OPM-NEXT: [[TMP16:%.*]] = icmp eq i32 [[TMP15]], [[TMP1]] ; IS________OPM-NEXT: br i1 [[TMP16]], label [[TMP6]], label [[TMP8]] ; ; IS________NPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable ; IS________NPM-LABEL: define {{[^@]+}}@loop_trip_count_unbound ; IS________NPM-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]], i32* nocapture nofree readonly [[TMP2:%.*]], i32 [[TMP3:%.*]]) local_unnamed_addr #[[ATTR14:[0-9]+]] { ; IS________NPM-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]] ; IS________NPM-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP8:%.*]] ; IS________NPM: 6: ; IS________NPM-NEXT: [[TMP7:%.*]] = phi i32 [ 0, [[TMP4:%.*]] ], [ [[TMP14:%.*]], [[TMP8]] ] ; IS________NPM-NEXT: ret i32 [[TMP7]] ; IS________NPM: 8: ; IS________NPM-NEXT: [[TMP9:%.*]] = phi i32 [ [[TMP15:%.*]], [[TMP8]] ], [ [[TMP0]], [[TMP4]] ] ; IS________NPM-NEXT: [[TMP10:%.*]] = phi i32 [ [[TMP14]], [[TMP8]] ], [ 0, [[TMP4]] ] ; IS________NPM-NEXT: [[TMP11:%.*]] = zext i32 [[TMP9]] to i64 ; IS________NPM-NEXT: [[TMP12:%.*]] = getelementptr inbounds i32, i32* [[TMP2]], i64 [[TMP11]] ; IS________NPM-NEXT: [[TMP13:%.*]] = load i32, i32* [[TMP12]], align 4 ; IS________NPM-NEXT: [[TMP14]] = add nsw i32 [[TMP13]], [[TMP10]] ; IS________NPM-NEXT: [[TMP15]] = add i32 [[TMP9]], [[TMP3]] ; IS________NPM-NEXT: [[TMP16:%.*]] = icmp eq i32 [[TMP15]], [[TMP1]] ; IS________NPM-NEXT: br i1 [[TMP16]], label [[TMP6]], label [[TMP8]] ; %5 = icmp eq i32 %0, %1 br i1 %5, label %6, label %8 ; <label>:6: ; preds = %8, %4 %7 = phi i32 [ 0, %4 ], [ %14, %8 ] ret i32 %7 ; <label>:8: ; preds = %4, %8 %9 = phi i32 [ %15, %8 ], [ %0, %4 ] %10 = phi i32 [ %14, %8 ], [ 0, %4 ] %11 = zext i32 %9 to i64 %12 = getelementptr inbounds i32, i32* %2, i64 %11 %13 = load i32, i32* %12, align 4 %14 = add nsw i32 %13, %10 %15 = add i32 %9, %3 %16 = icmp eq i32 %15, %1 br i1 %16, label %6, label %8 } ; TEST 13 (positive case) ; Function Attrs: norecurse nounwind readonly uwtable ; int loop_trip_dec(int n, int *p){ ; int ans = 0; ; for(;n >= 0;n--){ ; ans += p[n]; ; } ; return ans; ; } define i32 @loop_trip_dec(i32 %0, i32* nocapture readonly %1) local_unnamed_addr #0 { ; IS________OPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable ; IS________OPM-LABEL: define {{[^@]+}}@loop_trip_dec ; IS________OPM-SAME: (i32 [[TMP0:%.*]], i32* nocapture nofree readonly [[TMP1:%.*]]) local_unnamed_addr #[[ATTR13]] { ; IS________OPM-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], -1 ; IS________OPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP14:%.*]] ; IS________OPM: 4: ; IS________OPM-NEXT: [[TMP5:%.*]] = sext i32 [[TMP0]] to i64 ; IS________OPM-NEXT: br label [[TMP6:%.*]] ; IS________OPM: 6: ; IS________OPM-NEXT: [[TMP7:%.*]] = phi i64 [ [[TMP5]], [[TMP4]] ], [ [[TMP12:%.*]], [[TMP6]] ] ; IS________OPM-NEXT: [[TMP8:%.*]] = phi i32 [ 0, [[TMP4]] ], [ [[TMP11:%.*]], [[TMP6]] ] ; IS________OPM-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 [[TMP7]] ; IS________OPM-NEXT: [[TMP10:%.*]] = load i32, i32* [[TMP9]], align 4 ; IS________OPM-NEXT: [[TMP11]] = add nsw i32 [[TMP10]], [[TMP8]] ; IS________OPM-NEXT: [[TMP12]] = add nsw i64 [[TMP7]], -1 ; IS________OPM-NEXT: [[TMP13:%.*]] = icmp sgt i64 [[TMP7]], 0 ; IS________OPM-NEXT: br i1 [[TMP13]], label [[TMP6]], label [[TMP14]] ; IS________OPM: 14: ; IS________OPM-NEXT: [[TMP15:%.*]] = phi i32 [ 0, [[TMP2:%.*]] ], [ [[TMP11]], [[TMP6]] ] ; IS________OPM-NEXT: ret i32 [[TMP15]] ; ; IS________NPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable ; IS________NPM-LABEL: define {{[^@]+}}@loop_trip_dec ; IS________NPM-SAME: (i32 [[TMP0:%.*]], i32* nocapture nofree readonly [[TMP1:%.*]]) local_unnamed_addr #[[ATTR13]] { ; IS________NPM-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], -1 ; IS________NPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP14:%.*]] ; IS________NPM: 4: ; IS________NPM-NEXT: [[TMP5:%.*]] = sext i32 [[TMP0]] to i64 ; IS________NPM-NEXT: br label [[TMP6:%.*]] ; IS________NPM: 6: ; IS________NPM-NEXT: [[TMP7:%.*]] = phi i64 [ [[TMP5]], [[TMP4]] ], [ [[TMP12:%.*]], [[TMP6]] ] ; IS________NPM-NEXT: [[TMP8:%.*]] = phi i32 [ 0, [[TMP4]] ], [ [[TMP11:%.*]], [[TMP6]] ] ; IS________NPM-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 [[TMP7]] ; IS________NPM-NEXT: [[TMP10:%.*]] = load i32, i32* [[TMP9]], align 4 ; IS________NPM-NEXT: [[TMP11]] = add nsw i32 [[TMP10]], [[TMP8]] ; IS________NPM-NEXT: [[TMP12]] = add nsw i64 [[TMP7]], -1 ; IS________NPM-NEXT: [[TMP13:%.*]] = icmp sgt i64 [[TMP7]], 0 ; IS________NPM-NEXT: br i1 [[TMP13]], label [[TMP6]], label [[TMP14]] ; IS________NPM: 14: ; IS________NPM-NEXT: [[TMP15:%.*]] = phi i32 [ 0, [[TMP2:%.*]] ], [ [[TMP11]], [[TMP6]] ] ; IS________NPM-NEXT: ret i32 [[TMP15]] ; %3 = icmp sgt i32 %0, -1 br i1 %3, label %4, label %14 ; <label>:4: ; preds = %2 %5 = sext i32 %0 to i64 br label %6 ; <label>:6: ; preds = %4, %6 %7 = phi i64 [ %5, %4 ], [ %12, %6 ] %8 = phi i32 [ 0, %4 ], [ %11, %6 ] %9 = getelementptr inbounds i32, i32* %1, i64 %7 %10 = load i32, i32* %9, align 4 %11 = add nsw i32 %10, %8 %12 = add nsw i64 %7, -1 %13 = icmp sgt i64 %7, 0 br i1 %13, label %6, label %14 ; <label>:14: ; preds = %6, %2 %15 = phi i32 [ 0, %2 ], [ %11, %6 ] ret i32 %15 } ; TEST 14 (positive case) ; multiple return define i32 @multiple_return(i32 %a) #0 { ; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable ; CHECK-LABEL: define {{[^@]+}}@multiple_return ; CHECK-SAME: (i32 [[A:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[B:%.*]] = icmp eq i32 [[A]], 0 ; CHECK-NEXT: br i1 [[B]], label [[T:%.*]], label [[F:%.*]] ; CHECK: t: ; CHECK-NEXT: ret i32 1 ; CHECK: f: ; CHECK-NEXT: ret i32 0 ; %b = icmp eq i32 %a, 0 br i1 %b, label %t, label %f t: ret i32 1 f: ret i32 0 } ; TEST 15 (positive & negative case) ; unreachable exit ; 15.1 (positive case) define void @unreachable_exit_positive1() #0 { ; IS________OPM: Function Attrs: noinline nounwind willreturn uwtable ; IS________OPM-LABEL: define {{[^@]+}}@unreachable_exit_positive1 ; IS________OPM-SAME: () #[[ATTR10]] { ; IS________OPM-NEXT: tail call void @will_return() #[[ATTR28]] ; IS________OPM-NEXT: ret void ; IS________OPM: unreachable_label: ; IS________OPM-NEXT: unreachable ; ; IS________NPM: Function Attrs: noinline nounwind willreturn uwtable ; IS________NPM-LABEL: define {{[^@]+}}@unreachable_exit_positive1 ; IS________NPM-SAME: () #[[ATTR10]] { ; IS________NPM-NEXT: tail call void @will_return() #[[ATTR30]] ; IS________NPM-NEXT: ret void ; IS________NPM: unreachable_label: ; IS________NPM-NEXT: unreachable ; tail call void @will_return() ret void unreachable_label: tail call void @exit(i32 0) unreachable } define i32 @unreachable_exit_positive2(i32) local_unnamed_addr #0 { ; IS________OPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable ; IS________OPM-LABEL: define {{[^@]+}}@unreachable_exit_positive2 ; IS________OPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] { ; IS________OPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 1 ; IS________OPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] ; IS________OPM: 3: ; IS________OPM-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[TMP1:%.*]] ], [ [[TMP8:%.*]], [[TMP5]] ] ; IS________OPM-NEXT: ret i32 [[TMP4]] ; IS________OPM: 5: ; IS________OPM-NEXT: [[TMP6:%.*]] = phi i32 [ [[TMP9:%.*]], [[TMP5]] ], [ 1, [[TMP1]] ] ; IS________OPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8]], [[TMP5]] ], [ 1, [[TMP1]] ] ; IS________OPM-NEXT: [[TMP8]] = mul nsw i32 [[TMP6]], [[TMP7]] ; IS________OPM-NEXT: [[TMP9]] = add nuw nsw i32 [[TMP6]], 1 ; IS________OPM-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP6]], [[TMP0]] ; IS________OPM-NEXT: br i1 [[TMP10]], label [[TMP3]], label [[TMP5]] ; IS________OPM: unreachable_label: ; IS________OPM-NEXT: unreachable ; ; IS________NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable ; IS________NPM-LABEL: define {{[^@]+}}@unreachable_exit_positive2 ; IS________NPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] { ; IS________NPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 1 ; IS________NPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] ; IS________NPM: 3: ; IS________NPM-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[TMP1:%.*]] ], [ [[TMP8:%.*]], [[TMP5]] ] ; IS________NPM-NEXT: ret i32 [[TMP4]] ; IS________NPM: 5: ; IS________NPM-NEXT: [[TMP6:%.*]] = phi i32 [ [[TMP9:%.*]], [[TMP5]] ], [ 1, [[TMP1]] ] ; IS________NPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8]], [[TMP5]] ], [ 1, [[TMP1]] ] ; IS________NPM-NEXT: [[TMP8]] = mul nsw i32 [[TMP6]], [[TMP7]] ; IS________NPM-NEXT: [[TMP9]] = add nuw nsw i32 [[TMP6]], 1 ; IS________NPM-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP6]], [[TMP0]] ; IS________NPM-NEXT: br i1 [[TMP10]], label [[TMP3]], label [[TMP5]] ; IS________NPM: unreachable_label: ; IS________NPM-NEXT: unreachable ; %2 = icmp slt i32 %0, 1 br i1 %2, label %3, label %5 ; <label>:3: ; preds = %5, %1 %4 = phi i32 [ 1, %1 ], [ %8, %5 ] ret i32 %4 ; <label>:5: ; preds = %1, %5 %6 = phi i32 [ %9, %5 ], [ 1, %1 ] %7 = phi i32 [ %8, %5 ], [ 1, %1 ] %8 = mul nsw i32 %6, %7 %9 = add nuw nsw i32 %6, 1 %10 = icmp eq i32 %6, %0 br i1 %10, label %3, label %5 unreachable_label: tail call void @exit(i32 0) unreachable } ;15.2 define void @unreachable_exit_negative1() #0 { ; CHECK: Function Attrs: noinline nounwind uwtable ; CHECK-LABEL: define {{[^@]+}}@unreachable_exit_negative1 ; CHECK-SAME: () #[[ATTR7]] { ; CHECK-NEXT: tail call void @exit(i32 noundef 0) #[[ATTR5]] ; CHECK-NEXT: unreachable ; CHECK: unreachable_label: ; CHECK-NEXT: unreachable ; tail call void @exit(i32 0) ret void unreachable_label: tail call void @exit(i32 0) unreachable } define void @unreachable_exit_negative2() #0 { ; IS________OPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable ; IS________OPM-LABEL: define {{[^@]+}}@unreachable_exit_negative2 ; IS________OPM-SAME: () #[[ATTR14:[0-9]+]] { ; IS________OPM-NEXT: br label [[L1:%.*]] ; IS________OPM: L1: ; IS________OPM-NEXT: br label [[L2:%.*]] ; IS________OPM: L2: ; IS________OPM-NEXT: br label [[L1]] ; IS________OPM: unreachable_label: ; IS________OPM-NEXT: unreachable ; ; IS________NPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable ; IS________NPM-LABEL: define {{[^@]+}}@unreachable_exit_negative2 ; IS________NPM-SAME: () #[[ATTR15:[0-9]+]] { ; IS________NPM-NEXT: br label [[L1:%.*]] ; IS________NPM: L1: ; IS________NPM-NEXT: br label [[L2:%.*]] ; IS________NPM: L2: ; IS________NPM-NEXT: br label [[L1]] ; IS________NPM: unreachable_label: ; IS________NPM-NEXT: unreachable ; br label %L1 L1: br label %L2 L2: br label %L1 unreachable_label: tail call void @exit(i32 0) unreachable } ; CHECK: Function Attrs: noreturn nounwind ; CHECK-NEXT: declare void @llvm.eh.sjlj.longjmp(i8*) declare void @llvm.eh.sjlj.longjmp(i8*) define void @call_longjmp(i8* nocapture readnone %0) local_unnamed_addr #0 { ; CHECK: Function Attrs: noinline nounwind uwtable ; CHECK-LABEL: define {{[^@]+}}@call_longjmp ; CHECK-SAME: (i8* nocapture readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR7]] { ; CHECK-NEXT: tail call void @llvm.eh.sjlj.longjmp(i8* noalias readnone [[TMP0]]) #[[ATTR5]] ; CHECK-NEXT: unreachable ; tail call void @llvm.eh.sjlj.longjmp(i8* %0) ret void } ; TEST 16 (negative case) ; int infinite_loop_inside_bounded_loop(int n) { ; int ans = 0; ; for (int i = 0; i < n; i++) { ; while (1) ; ans++; ; } ; return ans; ; } define i32 @infinite_loop_inside_bounded_loop(i32 %n) { ; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone ; IS________OPM-LABEL: define {{[^@]+}}@infinite_loop_inside_bounded_loop ; IS________OPM-SAME: (i32 [[N:%.*]]) #[[ATTR16:[0-9]+]] { ; IS________OPM-NEXT: entry: ; IS________OPM-NEXT: br label [[FOR_COND:%.*]] ; IS________OPM: for.cond: ; IS________OPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N]], 0 ; IS________OPM-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] ; IS________OPM: for.cond.cleanup: ; IS________OPM-NEXT: br label [[FOR_END:%.*]] ; IS________OPM: for.body: ; IS________OPM-NEXT: br label [[WHILE_COND:%.*]] ; IS________OPM: while.cond: ; IS________OPM-NEXT: br label [[WHILE_BODY:%.*]] ; IS________OPM: while.body: ; IS________OPM-NEXT: br label [[WHILE_COND]] ; IS________OPM: for.inc: ; IS________OPM-NEXT: unreachable ; IS________OPM: for.end: ; IS________OPM-NEXT: ret i32 0 ; ; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone ; IS________NPM-LABEL: define {{[^@]+}}@infinite_loop_inside_bounded_loop ; IS________NPM-SAME: (i32 [[N:%.*]]) #[[ATTR17:[0-9]+]] { ; IS________NPM-NEXT: entry: ; IS________NPM-NEXT: br label [[FOR_COND:%.*]] ; IS________NPM: for.cond: ; IS________NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N]], 0 ; IS________NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] ; IS________NPM: for.cond.cleanup: ; IS________NPM-NEXT: br label [[FOR_END:%.*]] ; IS________NPM: for.body: ; IS________NPM-NEXT: br label [[WHILE_COND:%.*]] ; IS________NPM: while.cond: ; IS________NPM-NEXT: br label [[WHILE_BODY:%.*]] ; IS________NPM: while.body: ; IS________NPM-NEXT: br label [[WHILE_COND]] ; IS________NPM: for.inc: ; IS________NPM-NEXT: unreachable ; IS________NPM: for.end: ; IS________NPM-NEXT: ret i32 0 ; entry: br label %for.cond for.cond: ; preds = %for.inc, %entry %cmp = icmp sgt i32 %n, 0 br i1 %cmp, label %for.body, label %for.cond.cleanup for.cond.cleanup: ; preds = %for.cond br label %for.end for.body: ; preds = %for.cond br label %while.cond while.cond: ; preds = %while.body, %for.body br label %while.body while.body: ; preds = %while.cond br label %while.cond for.inc: ; No predecessors! br label %for.cond for.end: ; preds = %for.cond.cleanup ret i32 0 } ; TEST 17 (positive case) ; Nested loops with constant max trip count ; int bounded_nested_loops(int n) { ; int ans = 0; ; for (int i = 0; i < n; i++) { ; while (n--) { ; ans++; ; } ; } ; return ans; ; } define i32 @bounded_nested_loops(i32 %n) { ; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone ; IS________OPM-LABEL: define {{[^@]+}}@bounded_nested_loops ; IS________OPM-SAME: (i32 [[N:%.*]]) #[[ATTR16]] { ; IS________OPM-NEXT: entry: ; IS________OPM-NEXT: br label [[FOR_COND:%.*]] ; IS________OPM: for.cond: ; IS________OPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC1:%.*]], [[FOR_INC:%.*]] ] ; IS________OPM-NEXT: [[ANS_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[TMP:%.*]], [[FOR_INC]] ] ; IS________OPM-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ -1, [[FOR_INC]] ] ; IS________OPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], [[N_ADDR_0]] ; IS________OPM-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] ; IS________OPM: for.cond.cleanup: ; IS________OPM-NEXT: [[ANS_0_LCSSA:%.*]] = phi i32 [ [[ANS_0]], [[FOR_COND]] ] ; IS________OPM-NEXT: br label [[FOR_END:%.*]] ; IS________OPM: for.body: ; IS________OPM-NEXT: br label [[WHILE_COND:%.*]] ; IS________OPM: while.cond: ; IS________OPM-NEXT: br i1 true, label [[WHILE_END:%.*]], label [[WHILE_BODY:%.*]] ; IS________OPM: while.body: ; IS________OPM-NEXT: unreachable ; IS________OPM: while.end: ; IS________OPM-NEXT: [[TMP]] = add i32 [[N_ADDR_0]], [[ANS_0]] ; IS________OPM-NEXT: br label [[FOR_INC]] ; IS________OPM: for.inc: ; IS________OPM-NEXT: [[INC1]] = add nuw nsw i32 [[I_0]], 1 ; IS________OPM-NEXT: br label [[FOR_COND]] ; IS________OPM: for.end: ; IS________OPM-NEXT: ret i32 [[ANS_0_LCSSA]] ; ; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS________NPM-LABEL: define {{[^@]+}}@bounded_nested_loops ; IS________NPM-SAME: (i32 [[N:%.*]]) #[[ATTR18:[0-9]+]] { ; IS________NPM-NEXT: entry: ; IS________NPM-NEXT: br label [[FOR_COND:%.*]] ; IS________NPM: for.cond: ; IS________NPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC1:%.*]], [[FOR_INC:%.*]] ] ; IS________NPM-NEXT: [[ANS_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[TMP:%.*]], [[FOR_INC]] ] ; IS________NPM-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ -1, [[FOR_INC]] ] ; IS________NPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], [[N_ADDR_0]] ; IS________NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] ; IS________NPM: for.cond.cleanup: ; IS________NPM-NEXT: [[ANS_0_LCSSA:%.*]] = phi i32 [ [[ANS_0]], [[FOR_COND]] ] ; IS________NPM-NEXT: br label [[FOR_END:%.*]] ; IS________NPM: for.body: ; IS________NPM-NEXT: br label [[WHILE_COND:%.*]] ; IS________NPM: while.cond: ; IS________NPM-NEXT: br i1 true, label [[WHILE_END:%.*]], label [[WHILE_BODY:%.*]] ; IS________NPM: while.body: ; IS________NPM-NEXT: unreachable ; IS________NPM: while.end: ; IS________NPM-NEXT: [[TMP]] = add i32 [[N_ADDR_0]], [[ANS_0]] ; IS________NPM-NEXT: br label [[FOR_INC]] ; IS________NPM: for.inc: ; IS________NPM-NEXT: [[INC1]] = add nuw nsw i32 [[I_0]], 1 ; IS________NPM-NEXT: br label [[FOR_COND]] ; IS________NPM: for.end: ; IS________NPM-NEXT: ret i32 [[ANS_0_LCSSA]] ; entry: br label %for.cond for.cond: ; preds = %for.inc, %entry %i.0 = phi i32 [ 0, %entry ], [ %inc1, %for.inc ] %ans.0 = phi i32 [ 0, %entry ], [ %tmp, %for.inc ] %n.addr.0 = phi i32 [ %n, %entry ], [ -1, %for.inc ] %cmp = icmp slt i32 %i.0, %n.addr.0 br i1 %cmp, label %for.body, label %for.cond.cleanup for.cond.cleanup: ; preds = %for.cond %ans.0.lcssa = phi i32 [ %ans.0, %for.cond ] br label %for.end for.body: ; preds = %for.cond br label %while.cond while.cond: ; preds = %while.body, %for.body br i1 true, label %while.end, label %while.body while.body: ; preds = %while.cond br label %while.cond while.end: ; preds = %while.cond %tmp = add i32 %n.addr.0, %ans.0 br label %for.inc for.inc: ; preds = %while.end %inc1 = add nuw nsw i32 %i.0, 1 br label %for.cond for.end: ; preds = %for.cond.cleanup ret i32 %ans.0.lcssa } ; TEST 18 (negative case) ; int bounded_loop_inside_unbounded_loop(int n) { ; int ans = 0; ; while (n++) { ; for (int i = 0; i < n; i++) { ; ans++; ; } ; } ; return ans; ; } define i32 @bounded_loop_inside_unbounded_loop(i32 %n) { ; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone ; IS________OPM-LABEL: define {{[^@]+}}@bounded_loop_inside_unbounded_loop ; IS________OPM-SAME: (i32 [[N:%.*]]) #[[ATTR16]] { ; IS________OPM-NEXT: entry: ; IS________OPM-NEXT: br label [[WHILE_COND:%.*]] ; IS________OPM: while.cond: ; IS________OPM-NEXT: [[ANS_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2:%.*]], [[FOR_END:%.*]] ] ; IS________OPM-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ [[INC:%.*]], [[FOR_END]] ] ; IS________OPM-NEXT: [[TMP:%.*]] = icmp sgt i32 [[N_ADDR_0]], -1 ; IS________OPM-NEXT: [[SMAX:%.*]] = select i1 [[TMP]], i32 [[N_ADDR_0]], i32 -1 ; IS________OPM-NEXT: [[INC]] = add nsw i32 [[N_ADDR_0]], 1 ; IS________OPM-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[N_ADDR_0]], 0 ; IS________OPM-NEXT: br i1 [[TOBOOL]], label [[WHILE_END:%.*]], label [[WHILE_BODY:%.*]] ; IS________OPM: while.body: ; IS________OPM-NEXT: [[TMP1:%.*]] = add i32 [[ANS_0]], 1 ; IS________OPM-NEXT: br label [[FOR_COND:%.*]] ; IS________OPM: for.cond: ; IS________OPM-NEXT: br i1 true, label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY:%.*]] ; IS________OPM: for.cond.cleanup: ; IS________OPM-NEXT: [[TMP2]] = add i32 [[TMP1]], [[SMAX]] ; IS________OPM-NEXT: br label [[FOR_END]] ; IS________OPM: for.body: ; IS________OPM-NEXT: unreachable ; IS________OPM: for.inc: ; IS________OPM-NEXT: unreachable ; IS________OPM: for.end: ; IS________OPM-NEXT: br label [[WHILE_COND]] ; IS________OPM: while.end: ; IS________OPM-NEXT: [[ANS_0_LCSSA:%.*]] = phi i32 [ [[ANS_0]], [[WHILE_COND]] ] ; IS________OPM-NEXT: ret i32 [[ANS_0_LCSSA]] ; ; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone ; IS________NPM-LABEL: define {{[^@]+}}@bounded_loop_inside_unbounded_loop ; IS________NPM-SAME: (i32 [[N:%.*]]) #[[ATTR17]] { ; IS________NPM-NEXT: entry: ; IS________NPM-NEXT: br label [[WHILE_COND:%.*]] ; IS________NPM: while.cond: ; IS________NPM-NEXT: [[ANS_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2:%.*]], [[FOR_END:%.*]] ] ; IS________NPM-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ [[INC:%.*]], [[FOR_END]] ] ; IS________NPM-NEXT: [[TMP:%.*]] = icmp sgt i32 [[N_ADDR_0]], -1 ; IS________NPM-NEXT: [[SMAX:%.*]] = select i1 [[TMP]], i32 [[N_ADDR_0]], i32 -1 ; IS________NPM-NEXT: [[INC]] = add nsw i32 [[N_ADDR_0]], 1 ; IS________NPM-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[N_ADDR_0]], 0 ; IS________NPM-NEXT: br i1 [[TOBOOL]], label [[WHILE_END:%.*]], label [[WHILE_BODY:%.*]] ; IS________NPM: while.body: ; IS________NPM-NEXT: [[TMP1:%.*]] = add i32 [[ANS_0]], 1 ; IS________NPM-NEXT: br label [[FOR_COND:%.*]] ; IS________NPM: for.cond: ; IS________NPM-NEXT: br i1 true, label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY:%.*]] ; IS________NPM: for.cond.cleanup: ; IS________NPM-NEXT: [[TMP2]] = add i32 [[TMP1]], [[SMAX]] ; IS________NPM-NEXT: br label [[FOR_END]] ; IS________NPM: for.body: ; IS________NPM-NEXT: unreachable ; IS________NPM: for.inc: ; IS________NPM-NEXT: unreachable ; IS________NPM: for.end: ; IS________NPM-NEXT: br label [[WHILE_COND]] ; IS________NPM: while.end: ; IS________NPM-NEXT: [[ANS_0_LCSSA:%.*]] = phi i32 [ [[ANS_0]], [[WHILE_COND]] ] ; IS________NPM-NEXT: ret i32 [[ANS_0_LCSSA]] ; entry: br label %while.cond while.cond: ; preds = %for.end, %entry %ans.0 = phi i32 [ 0, %entry ], [ %tmp2, %for.end ] %n.addr.0 = phi i32 [ %n, %entry ], [ %inc, %for.end ] %tmp = icmp sgt i32 %n.addr.0, -1 %smax = select i1 %tmp, i32 %n.addr.0, i32 -1 %inc = add nsw i32 %n.addr.0, 1 %tobool = icmp eq i32 %n.addr.0, 0 br i1 %tobool, label %while.end, label %while.body while.body: ; preds = %while.cond %tmp1 = add i32 %ans.0, 1 br label %for.cond for.cond: ; preds = %for.inc, %while.body br i1 true, label %for.cond.cleanup, label %for.body for.cond.cleanup: ; preds = %for.cond %tmp2 = add i32 %tmp1, %smax br label %for.end for.body: ; preds = %for.cond br label %for.inc for.inc: ; preds = %for.body br label %for.cond for.end: ; preds = %for.cond.cleanup br label %while.cond while.end: ; preds = %while.cond %ans.0.lcssa = phi i32 [ %ans.0, %while.cond ] ret i32 %ans.0.lcssa } ; TEST 19 (negative case) ; int nested_unbounded_loops(int n) { ; int ans = 0; ; while (n--) { ; while (n--) { ; ans++; ; } ; while (n--) { ; ans++; ; } ; } ; return ans; ; } define i32 @nested_unbounded_loops(i32 %n) { ; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone ; IS________OPM-LABEL: define {{[^@]+}}@nested_unbounded_loops ; IS________OPM-SAME: (i32 [[N:%.*]]) #[[ATTR16]] { ; IS________OPM-NEXT: entry: ; IS________OPM-NEXT: br label [[WHILE_COND:%.*]] ; IS________OPM: while.cond: ; IS________OPM-NEXT: [[ANS_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP1:%.*]], [[WHILE_END10:%.*]] ] ; IS________OPM-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ -1, [[WHILE_END10]] ] ; IS________OPM-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[N_ADDR_0]], 0 ; IS________OPM-NEXT: br i1 [[TOBOOL]], label [[WHILE_END11:%.*]], label [[WHILE_BODY:%.*]] ; IS________OPM: while.body: ; IS________OPM-NEXT: br label [[WHILE_COND1:%.*]] ; IS________OPM: while.cond1: ; IS________OPM-NEXT: br i1 true, label [[WHILE_END:%.*]], label [[WHILE_BODY4:%.*]] ; IS________OPM: while.body4: ; IS________OPM-NEXT: unreachable ; IS________OPM: while.end: ; IS________OPM-NEXT: [[TMP:%.*]] = add i32 [[N_ADDR_0]], -2 ; IS________OPM-NEXT: br label [[WHILE_COND5:%.*]] ; IS________OPM: while.cond5: ; IS________OPM-NEXT: br i1 true, label [[WHILE_END10]], label [[WHILE_BODY8:%.*]] ; IS________OPM: while.body8: ; IS________OPM-NEXT: unreachable ; IS________OPM: while.end10: ; IS________OPM-NEXT: [[TMP1]] = add i32 [[TMP]], [[ANS_0]] ; IS________OPM-NEXT: br label [[WHILE_COND]] ; IS________OPM: while.end11: ; IS________OPM-NEXT: [[ANS_0_LCSSA:%.*]] = phi i32 [ [[ANS_0]], [[WHILE_COND]] ] ; IS________OPM-NEXT: ret i32 [[ANS_0_LCSSA]] ; ; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone ; IS________NPM-LABEL: define {{[^@]+}}@nested_unbounded_loops ; IS________NPM-SAME: (i32 [[N:%.*]]) #[[ATTR17]] { ; IS________NPM-NEXT: entry: ; IS________NPM-NEXT: br label [[WHILE_COND:%.*]] ; IS________NPM: while.cond: ; IS________NPM-NEXT: [[ANS_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP1:%.*]], [[WHILE_END10:%.*]] ] ; IS________NPM-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ -1, [[WHILE_END10]] ] ; IS________NPM-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[N_ADDR_0]], 0 ; IS________NPM-NEXT: br i1 [[TOBOOL]], label [[WHILE_END11:%.*]], label [[WHILE_BODY:%.*]] ; IS________NPM: while.body: ; IS________NPM-NEXT: br label [[WHILE_COND1:%.*]] ; IS________NPM: while.cond1: ; IS________NPM-NEXT: br i1 true, label [[WHILE_END:%.*]], label [[WHILE_BODY4:%.*]] ; IS________NPM: while.body4: ; IS________NPM-NEXT: unreachable ; IS________NPM: while.end: ; IS________NPM-NEXT: [[TMP:%.*]] = add i32 [[N_ADDR_0]], -2 ; IS________NPM-NEXT: br label [[WHILE_COND5:%.*]] ; IS________NPM: while.cond5: ; IS________NPM-NEXT: br i1 true, label [[WHILE_END10]], label [[WHILE_BODY8:%.*]] ; IS________NPM: while.body8: ; IS________NPM-NEXT: unreachable ; IS________NPM: while.end10: ; IS________NPM-NEXT: [[TMP1]] = add i32 [[TMP]], [[ANS_0]] ; IS________NPM-NEXT: br label [[WHILE_COND]] ; IS________NPM: while.end11: ; IS________NPM-NEXT: [[ANS_0_LCSSA:%.*]] = phi i32 [ [[ANS_0]], [[WHILE_COND]] ] ; IS________NPM-NEXT: ret i32 [[ANS_0_LCSSA]] ; entry: br label %while.cond while.cond: ; preds = %while.end10, %entry %ans.0 = phi i32 [ 0, %entry ], [ %tmp1, %while.end10 ] %n.addr.0 = phi i32 [ %n, %entry ], [ -1, %while.end10 ] %tobool = icmp eq i32 %n.addr.0, 0 br i1 %tobool, label %while.end11, label %while.body while.body: ; preds = %while.cond br label %while.cond1 while.cond1: ; preds = %while.body4, %while.body br i1 true, label %while.end, label %while.body4 while.body4: ; preds = %while.cond1 br label %while.cond1 while.end: ; preds = %while.cond1 %tmp = add i32 %n.addr.0, -2 br label %while.cond5 while.cond5: ; preds = %while.body8, %while.end br i1 true, label %while.end10, label %while.body8 while.body8: ; preds = %while.cond5 br label %while.cond5 while.end10: ; preds = %while.cond5 %tmp1 = add i32 %tmp, %ans.0 br label %while.cond while.end11: ; preds = %while.cond %ans.0.lcssa = phi i32 [ %ans.0, %while.cond ] ret i32 %ans.0.lcssa } ; TEST 20 (negative case) ; void non_loop_cycle(int n) { ; if (fact_loop(n)>5) ; goto entry1; ; else ; goto entry2; ; ; entry1: ; if (fact_loop(n)>5) ; goto exit; ; else ; goto entry2; ; entry2: ; if (fact_loop(n)>5) ; goto exit; ; else ; goto entry1; ; exit: ; return; ; } define void @non_loop_cycle(i32 %n) { ; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@non_loop_cycle ; IS__TUNIT_OPM-SAME: (i32 [[N:%.*]]) #[[ATTR16]] { ; IS__TUNIT_OPM-NEXT: entry: ; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR24]] ; IS__TUNIT_OPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 5 ; IS__TUNIT_OPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] ; IS__TUNIT_OPM: if.then: ; IS__TUNIT_OPM-NEXT: br label [[ENTRY1:%.*]] ; IS__TUNIT_OPM: if.else: ; IS__TUNIT_OPM-NEXT: br label [[ENTRY2:%.*]] ; IS__TUNIT_OPM: entry1: ; IS__TUNIT_OPM-NEXT: [[CALL1:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR24]] ; IS__TUNIT_OPM-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[CALL1]], 5 ; IS__TUNIT_OPM-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_ELSE4:%.*]] ; IS__TUNIT_OPM: if.then3: ; IS__TUNIT_OPM-NEXT: br label [[EXIT:%.*]] ; IS__TUNIT_OPM: if.else4: ; IS__TUNIT_OPM-NEXT: br label [[ENTRY2]] ; IS__TUNIT_OPM: entry2: ; IS__TUNIT_OPM-NEXT: [[CALL5:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR24]] ; IS__TUNIT_OPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[CALL5]], 5 ; IS__TUNIT_OPM-NEXT: br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_ELSE8:%.*]] ; IS__TUNIT_OPM: if.then7: ; IS__TUNIT_OPM-NEXT: br label [[EXIT]] ; IS__TUNIT_OPM: if.else8: ; IS__TUNIT_OPM-NEXT: br label [[ENTRY1]] ; IS__TUNIT_OPM: exit: ; IS__TUNIT_OPM-NEXT: ret void ; ; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@non_loop_cycle ; IS__TUNIT_NPM-SAME: (i32 [[N:%.*]]) #[[ATTR17]] { ; IS__TUNIT_NPM-NEXT: entry: ; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR26]] ; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 5 ; IS__TUNIT_NPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] ; IS__TUNIT_NPM: if.then: ; IS__TUNIT_NPM-NEXT: br label [[ENTRY1:%.*]] ; IS__TUNIT_NPM: if.else: ; IS__TUNIT_NPM-NEXT: br label [[ENTRY2:%.*]] ; IS__TUNIT_NPM: entry1: ; IS__TUNIT_NPM-NEXT: [[CALL1:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR26]] ; IS__TUNIT_NPM-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[CALL1]], 5 ; IS__TUNIT_NPM-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_ELSE4:%.*]] ; IS__TUNIT_NPM: if.then3: ; IS__TUNIT_NPM-NEXT: br label [[EXIT:%.*]] ; IS__TUNIT_NPM: if.else4: ; IS__TUNIT_NPM-NEXT: br label [[ENTRY2]] ; IS__TUNIT_NPM: entry2: ; IS__TUNIT_NPM-NEXT: [[CALL5:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR26]] ; IS__TUNIT_NPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[CALL5]], 5 ; IS__TUNIT_NPM-NEXT: br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_ELSE8:%.*]] ; IS__TUNIT_NPM: if.then7: ; IS__TUNIT_NPM-NEXT: br label [[EXIT]] ; IS__TUNIT_NPM: if.else8: ; IS__TUNIT_NPM-NEXT: br label [[ENTRY1]] ; IS__TUNIT_NPM: exit: ; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@non_loop_cycle ; IS__CGSCC_OPM-SAME: (i32 [[N:%.*]]) #[[ATTR17]] { ; IS__CGSCC_OPM-NEXT: entry: ; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR29:[0-9]+]] ; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 5 ; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] ; IS__CGSCC_OPM: if.then: ; IS__CGSCC_OPM-NEXT: br label [[ENTRY1:%.*]] ; IS__CGSCC_OPM: if.else: ; IS__CGSCC_OPM-NEXT: br label [[ENTRY2:%.*]] ; IS__CGSCC_OPM: entry1: ; IS__CGSCC_OPM-NEXT: [[CALL1:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR29]] ; IS__CGSCC_OPM-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[CALL1]], 5 ; IS__CGSCC_OPM-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_ELSE4:%.*]] ; IS__CGSCC_OPM: if.then3: ; IS__CGSCC_OPM-NEXT: br label [[EXIT:%.*]] ; IS__CGSCC_OPM: if.else4: ; IS__CGSCC_OPM-NEXT: br label [[ENTRY2]] ; IS__CGSCC_OPM: entry2: ; IS__CGSCC_OPM-NEXT: [[CALL5:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR29]] ; IS__CGSCC_OPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[CALL5]], 5 ; IS__CGSCC_OPM-NEXT: br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_ELSE8:%.*]] ; IS__CGSCC_OPM: if.then7: ; IS__CGSCC_OPM-NEXT: br label [[EXIT]] ; IS__CGSCC_OPM: if.else8: ; IS__CGSCC_OPM-NEXT: br label [[ENTRY1]] ; IS__CGSCC_OPM: exit: ; IS__CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@non_loop_cycle ; IS__CGSCC_NPM-SAME: (i32 [[N:%.*]]) #[[ATTR19]] { ; IS__CGSCC_NPM-NEXT: entry: ; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32 @fact_loop(i32 [[N]]) ; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 5 ; IS__CGSCC_NPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] ; IS__CGSCC_NPM: if.then: ; IS__CGSCC_NPM-NEXT: br label [[ENTRY1:%.*]] ; IS__CGSCC_NPM: if.else: ; IS__CGSCC_NPM-NEXT: br label [[ENTRY2:%.*]] ; IS__CGSCC_NPM: entry1: ; IS__CGSCC_NPM-NEXT: [[CALL1:%.*]] = call i32 @fact_loop(i32 [[N]]) ; IS__CGSCC_NPM-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[CALL1]], 5 ; IS__CGSCC_NPM-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_ELSE4:%.*]] ; IS__CGSCC_NPM: if.then3: ; IS__CGSCC_NPM-NEXT: br label [[EXIT:%.*]] ; IS__CGSCC_NPM: if.else4: ; IS__CGSCC_NPM-NEXT: br label [[ENTRY2]] ; IS__CGSCC_NPM: entry2: ; IS__CGSCC_NPM-NEXT: [[CALL5:%.*]] = call i32 @fact_loop(i32 [[N]]) ; IS__CGSCC_NPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[CALL5]], 5 ; IS__CGSCC_NPM-NEXT: br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_ELSE8:%.*]] ; IS__CGSCC_NPM: if.then7: ; IS__CGSCC_NPM-NEXT: br label [[EXIT]] ; IS__CGSCC_NPM: if.else8: ; IS__CGSCC_NPM-NEXT: br label [[ENTRY1]] ; IS__CGSCC_NPM: exit: ; IS__CGSCC_NPM-NEXT: ret void ; entry: %call = call i32 @fact_loop(i32 %n) %cmp = icmp sgt i32 %call, 5 br i1 %cmp, label %if.then, label %if.else if.then: ; preds = %entry br label %entry1 if.else: ; preds = %entry br label %entry2 entry1: ; preds = %if.else8, %if.then %call1 = call i32 @fact_loop(i32 %n) %cmp2 = icmp sgt i32 %call1, 5 br i1 %cmp2, label %if.then3, label %if.else4 if.then3: ; preds = %entry1 br label %exit if.else4: ; preds = %entry1 br label %entry2 entry2: ; preds = %if.else4, %if.else %call5 = call i32 @fact_loop(i32 %n) %cmp6 = icmp sgt i32 %call5, 5 br i1 %cmp6, label %if.then7, label %if.else8 if.then7: ; preds = %entry2 br label %exit if.else8: ; preds = %entry2 br label %entry1 exit: ; preds = %if.then7, %if.then3 ret void } declare void @unknown() declare void @readonly() readonly declare void @readnone() readnone declare void @unknown_mustprogress() mustprogress declare void @readonly_mustprogress() readonly mustprogress define void @willreturn_mustprogress_caller_1() mustprogress { ; IS__TUNIT_OPM: Function Attrs: mustprogress ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_1 ; IS__TUNIT_OPM-SAME: () #[[ATTR19:[0-9]+]] { ; IS__TUNIT_OPM-NEXT: call void @unknown() ; IS__TUNIT_OPM-NEXT: ret void ; ; IS__TUNIT_NPM: Function Attrs: mustprogress ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_1 ; IS__TUNIT_NPM-SAME: () #[[ATTR21:[0-9]+]] { ; IS__TUNIT_NPM-NEXT: call void @unknown() ; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC_OPM: Function Attrs: mustprogress ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_1 ; IS__CGSCC_OPM-SAME: () #[[ATTR20:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: call void @unknown() ; IS__CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_NPM: Function Attrs: mustprogress ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_1 ; IS__CGSCC_NPM-SAME: () #[[ATTR22:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: call void @unknown() ; IS__CGSCC_NPM-NEXT: ret void ; call void @unknown() ret void } define void @willreturn_mustprogress_caller_2() mustprogress { ; IS__TUNIT_OPM: Function Attrs: mustprogress readonly willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_2 ; IS__TUNIT_OPM-SAME: () #[[ATTR21:[0-9]+]] { ; IS__TUNIT_OPM-NEXT: call void @readonly() #[[ATTR17:[0-9]+]] ; IS__TUNIT_OPM-NEXT: ret void ; ; IS__TUNIT_NPM: Function Attrs: mustprogress readonly willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_2 ; IS__TUNIT_NPM-SAME: () #[[ATTR23:[0-9]+]] { ; IS__TUNIT_NPM-NEXT: call void @readonly() #[[ATTR19:[0-9]+]] ; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC_OPM: Function Attrs: mustprogress readonly willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_2 ; IS__CGSCC_OPM-SAME: () #[[ATTR22:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: call void @readonly() #[[ATTR18:[0-9]+]] ; IS__CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_NPM: Function Attrs: mustprogress readonly willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_2 ; IS__CGSCC_NPM-SAME: () #[[ATTR24:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: call void @readonly() #[[ATTR20:[0-9]+]] ; IS__CGSCC_NPM-NEXT: ret void ; call void @readonly() ret void } define void @willreturn_mustprogress_caller_3() mustprogress { ; IS__TUNIT_OPM: Function Attrs: mustprogress nosync readnone willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_3 ; IS__TUNIT_OPM-SAME: () #[[ATTR22:[0-9]+]] { ; IS__TUNIT_OPM-NEXT: call void @readnone() ; IS__TUNIT_OPM-NEXT: ret void ; ; IS__TUNIT_NPM: Function Attrs: mustprogress nosync readnone willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_3 ; IS__TUNIT_NPM-SAME: () #[[ATTR24:[0-9]+]] { ; IS__TUNIT_NPM-NEXT: call void @readnone() ; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC_OPM: Function Attrs: mustprogress nosync readnone willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_3 ; IS__CGSCC_OPM-SAME: () #[[ATTR23:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: call void @readnone() ; IS__CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_NPM: Function Attrs: mustprogress nosync readnone willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_3 ; IS__CGSCC_NPM-SAME: () #[[ATTR25:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: call void @readnone() ; IS__CGSCC_NPM-NEXT: ret void ; call void @readnone() ret void } define void @willreturn_mustprogress_callee_1() { ; CHECK-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_1() { ; CHECK-NEXT: call void @unknown_mustprogress() ; CHECK-NEXT: ret void ; call void @unknown_mustprogress() ret void } define void @willreturn_mustprogress_callee_2() { ; IS__TUNIT_OPM: Function Attrs: readonly willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_2 ; IS__TUNIT_OPM-SAME: () #[[ATTR23:[0-9]+]] { ; IS__TUNIT_OPM-NEXT: call void @readonly_mustprogress() #[[ATTR23]] ; IS__TUNIT_OPM-NEXT: ret void ; ; IS__TUNIT_NPM: Function Attrs: readonly willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_2 ; IS__TUNIT_NPM-SAME: () #[[ATTR25:[0-9]+]] { ; IS__TUNIT_NPM-NEXT: call void @readonly_mustprogress() #[[ATTR25]] ; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC_OPM: Function Attrs: readonly willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_2 ; IS__CGSCC_OPM-SAME: () #[[ATTR24:[0-9]+]] { ; IS__CGSCC_OPM-NEXT: call void @readonly_mustprogress() #[[ATTR24]] ; IS__CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_NPM: Function Attrs: readonly willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_2 ; IS__CGSCC_NPM-SAME: () #[[ATTR26:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: call void @readonly_mustprogress() #[[ATTR26]] ; IS__CGSCC_NPM-NEXT: ret void ; call void @readonly_mustprogress() ret void } define void @willreturn_mustprogress_callee_3() { ; CHECK-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_3() { ; CHECK-NEXT: call void @willreturn_mustprogress_callee_1() ; CHECK-NEXT: ret void ; call void @willreturn_mustprogress_callee_1() ret void } define void @willreturn_mustprogress_callee_4() { ; IS__TUNIT_OPM: Function Attrs: readonly willreturn ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_4 ; IS__TUNIT_OPM-SAME: () #[[ATTR23]] { ; IS__TUNIT_OPM-NEXT: call void @willreturn_mustprogress_callee_2() #[[ATTR23]] ; IS__TUNIT_OPM-NEXT: ret void ; ; IS__TUNIT_NPM: Function Attrs: readonly willreturn ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_4 ; IS__TUNIT_NPM-SAME: () #[[ATTR25]] { ; IS__TUNIT_NPM-NEXT: call void @willreturn_mustprogress_callee_2() #[[ATTR25]] ; IS__TUNIT_NPM-NEXT: ret void ; ; IS__CGSCC_OPM: Function Attrs: readonly willreturn ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_4 ; IS__CGSCC_OPM-SAME: () #[[ATTR24]] { ; IS__CGSCC_OPM-NEXT: call void @willreturn_mustprogress_callee_2() #[[ATTR24]] ; IS__CGSCC_OPM-NEXT: ret void ; ; IS__CGSCC_NPM: Function Attrs: readonly willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_4 ; IS__CGSCC_NPM-SAME: () #[[ATTR26]] { ; IS__CGSCC_NPM-NEXT: call void @willreturn_mustprogress_callee_2() #[[ATTR26]] ; IS__CGSCC_NPM-NEXT: ret void ; call void @willreturn_mustprogress_callee_2() ret void } attributes #0 = { nounwind uwtable noinline } attributes #1 = { uwtable noinline } ;. ; IS__TUNIT_OPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } ; IS__TUNIT_OPM: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable } ; IS__TUNIT_OPM: attributes #[[ATTR2]] = { nofree noinline norecurse nosync nounwind readnone uwtable } ; IS__TUNIT_OPM: attributes #[[ATTR3:[0-9]+]] = { nofree nosync nounwind willreturn } ; IS__TUNIT_OPM: attributes #[[ATTR4]] = { nofree noinline nosync nounwind uwtable } ; IS__TUNIT_OPM: attributes #[[ATTR5]] = { noreturn } ; IS__TUNIT_OPM: attributes #[[ATTR6]] = { noinline noreturn nounwind uwtable } ; IS__TUNIT_OPM: attributes #[[ATTR7]] = { noinline nounwind uwtable } ; IS__TUNIT_OPM: attributes #[[ATTR8:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } ; IS__TUNIT_OPM: attributes #[[ATTR9:[0-9]+]] = { norecurse willreturn } ; IS__TUNIT_OPM: attributes #[[ATTR10]] = { noinline nounwind willreturn uwtable } ; IS__TUNIT_OPM: attributes #[[ATTR11:[0-9]+]] = { noinline willreturn uwtable } ; IS__TUNIT_OPM: attributes #[[ATTR12]] = { nounwind willreturn } ; IS__TUNIT_OPM: attributes #[[ATTR13]] = { argmemonly nofree noinline norecurse nosync nounwind readonly uwtable } ; IS__TUNIT_OPM: attributes #[[ATTR14]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable } ; IS__TUNIT_OPM: attributes #[[ATTR15:[0-9]+]] = { noreturn nounwind } ; IS__TUNIT_OPM: attributes #[[ATTR16]] = { nofree norecurse nosync nounwind readnone } ; IS__TUNIT_OPM: attributes #[[ATTR17]] = { readonly } ; IS__TUNIT_OPM: attributes #[[ATTR18:[0-9]+]] = { readnone } ; IS__TUNIT_OPM: attributes #[[ATTR19]] = { mustprogress } ; IS__TUNIT_OPM: attributes #[[ATTR20:[0-9]+]] = { mustprogress readonly } ; IS__TUNIT_OPM: attributes #[[ATTR21]] = { mustprogress readonly willreturn } ; IS__TUNIT_OPM: attributes #[[ATTR22]] = { mustprogress nosync readnone willreturn } ; IS__TUNIT_OPM: attributes #[[ATTR23]] = { readonly willreturn } ; IS__TUNIT_OPM: attributes #[[ATTR24]] = { nofree nosync nounwind readnone } ; IS__TUNIT_OPM: attributes #[[ATTR25]] = { nofree nosync nounwind } ; IS__TUNIT_OPM: attributes #[[ATTR26]] = { readnone willreturn } ; IS__TUNIT_OPM: attributes #[[ATTR27]] = { nounwind } ; IS__TUNIT_OPM: attributes #[[ATTR28]] = { willreturn } ;. ; IS__TUNIT_NPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } ; IS__TUNIT_NPM: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable } ; IS__TUNIT_NPM: attributes #[[ATTR2]] = { nofree noinline norecurse nosync nounwind readnone uwtable } ; IS__TUNIT_NPM: attributes #[[ATTR3:[0-9]+]] = { nofree nosync nounwind willreturn } ; IS__TUNIT_NPM: attributes #[[ATTR4]] = { nofree noinline nosync nounwind uwtable } ; IS__TUNIT_NPM: attributes #[[ATTR5]] = { noreturn } ; IS__TUNIT_NPM: attributes #[[ATTR6]] = { noinline noreturn nounwind uwtable } ; IS__TUNIT_NPM: attributes #[[ATTR7]] = { noinline nounwind uwtable } ; IS__TUNIT_NPM: attributes #[[ATTR8:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } ; IS__TUNIT_NPM: attributes #[[ATTR9:[0-9]+]] = { norecurse willreturn } ; IS__TUNIT_NPM: attributes #[[ATTR10]] = { noinline nounwind willreturn uwtable } ; IS__TUNIT_NPM: attributes #[[ATTR11:[0-9]+]] = { noinline willreturn uwtable } ; IS__TUNIT_NPM: attributes #[[ATTR12]] = { nounwind willreturn } ; IS__TUNIT_NPM: attributes #[[ATTR13]] = { argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable } ; IS__TUNIT_NPM: attributes #[[ATTR14]] = { argmemonly nofree noinline norecurse nosync nounwind readonly uwtable } ; IS__TUNIT_NPM: attributes #[[ATTR15]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable } ; IS__TUNIT_NPM: attributes #[[ATTR16:[0-9]+]] = { noreturn nounwind } ; IS__TUNIT_NPM: attributes #[[ATTR17]] = { nofree norecurse nosync nounwind readnone } ; IS__TUNIT_NPM: attributes #[[ATTR18]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__TUNIT_NPM: attributes #[[ATTR19]] = { readonly } ; IS__TUNIT_NPM: attributes #[[ATTR20:[0-9]+]] = { readnone } ; IS__TUNIT_NPM: attributes #[[ATTR21]] = { mustprogress } ; IS__TUNIT_NPM: attributes #[[ATTR22:[0-9]+]] = { mustprogress readonly } ; IS__TUNIT_NPM: attributes #[[ATTR23]] = { mustprogress readonly willreturn } ; IS__TUNIT_NPM: attributes #[[ATTR24]] = { mustprogress nosync readnone willreturn } ; IS__TUNIT_NPM: attributes #[[ATTR25]] = { readonly willreturn } ; IS__TUNIT_NPM: attributes #[[ATTR26]] = { nofree nosync nounwind readnone } ; IS__TUNIT_NPM: attributes #[[ATTR27]] = { nofree nosync nounwind } ; IS__TUNIT_NPM: attributes #[[ATTR28]] = { readnone willreturn } ; IS__TUNIT_NPM: attributes #[[ATTR29]] = { nounwind } ; IS__TUNIT_NPM: attributes #[[ATTR30]] = { willreturn } ;. ; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } ; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable } ; IS__CGSCC_OPM: attributes #[[ATTR2]] = { nofree noinline norecurse nosync nounwind readnone uwtable } ; IS__CGSCC_OPM: attributes #[[ATTR3:[0-9]+]] = { nofree nosync nounwind willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR4]] = { nofree noinline nosync nounwind uwtable } ; IS__CGSCC_OPM: attributes #[[ATTR5]] = { noreturn } ; IS__CGSCC_OPM: attributes #[[ATTR6]] = { noinline noreturn nounwind uwtable } ; IS__CGSCC_OPM: attributes #[[ATTR7]] = { noinline nounwind uwtable } ; IS__CGSCC_OPM: attributes #[[ATTR8:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR9:[0-9]+]] = { norecurse willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR10]] = { noinline nounwind willreturn uwtable } ; IS__CGSCC_OPM: attributes #[[ATTR11:[0-9]+]] = { noinline willreturn uwtable } ; IS__CGSCC_OPM: attributes #[[ATTR12]] = { nounwind willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR13]] = { argmemonly nofree noinline norecurse nosync nounwind readonly uwtable } ; IS__CGSCC_OPM: attributes #[[ATTR14]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable } ; IS__CGSCC_OPM: attributes #[[ATTR15:[0-9]+]] = { noreturn nounwind } ; IS__CGSCC_OPM: attributes #[[ATTR16]] = { nofree norecurse nosync nounwind readnone } ; IS__CGSCC_OPM: attributes #[[ATTR17]] = { nofree nosync nounwind readnone } ; IS__CGSCC_OPM: attributes #[[ATTR18]] = { readonly } ; IS__CGSCC_OPM: attributes #[[ATTR19:[0-9]+]] = { readnone } ; IS__CGSCC_OPM: attributes #[[ATTR20]] = { mustprogress } ; IS__CGSCC_OPM: attributes #[[ATTR21:[0-9]+]] = { mustprogress readonly } ; IS__CGSCC_OPM: attributes #[[ATTR22]] = { mustprogress readonly willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR23]] = { mustprogress nosync readnone willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR24]] = { readonly willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR25]] = { nofree nosync nounwind } ; IS__CGSCC_OPM: attributes #[[ATTR26]] = { readnone willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR27]] = { nounwind } ; IS__CGSCC_OPM: attributes #[[ATTR28]] = { willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR29]] = { nounwind readnone } ;. ; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } ; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable } ; IS__CGSCC_NPM: attributes #[[ATTR2]] = { nofree noinline norecurse nosync nounwind readnone uwtable } ; IS__CGSCC_NPM: attributes #[[ATTR3:[0-9]+]] = { nofree nosync nounwind willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR4]] = { nofree noinline nosync nounwind uwtable } ; IS__CGSCC_NPM: attributes #[[ATTR5]] = { noreturn } ; IS__CGSCC_NPM: attributes #[[ATTR6]] = { noinline noreturn nounwind uwtable } ; IS__CGSCC_NPM: attributes #[[ATTR7]] = { noinline nounwind uwtable } ; IS__CGSCC_NPM: attributes #[[ATTR8:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR9:[0-9]+]] = { norecurse willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR10]] = { noinline nounwind willreturn uwtable } ; IS__CGSCC_NPM: attributes #[[ATTR11:[0-9]+]] = { noinline willreturn uwtable } ; IS__CGSCC_NPM: attributes #[[ATTR12]] = { nounwind willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR13]] = { argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable } ; IS__CGSCC_NPM: attributes #[[ATTR14]] = { argmemonly nofree noinline norecurse nosync nounwind readonly uwtable } ; IS__CGSCC_NPM: attributes #[[ATTR15]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable } ; IS__CGSCC_NPM: attributes #[[ATTR16:[0-9]+]] = { noreturn nounwind } ; IS__CGSCC_NPM: attributes #[[ATTR17]] = { nofree norecurse nosync nounwind readnone } ; IS__CGSCC_NPM: attributes #[[ATTR18]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR19]] = { nofree nosync nounwind readnone } ; IS__CGSCC_NPM: attributes #[[ATTR20]] = { readonly } ; IS__CGSCC_NPM: attributes #[[ATTR21:[0-9]+]] = { readnone } ; IS__CGSCC_NPM: attributes #[[ATTR22]] = { mustprogress } ; IS__CGSCC_NPM: attributes #[[ATTR23:[0-9]+]] = { mustprogress readonly } ; IS__CGSCC_NPM: attributes #[[ATTR24]] = { mustprogress readonly willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR25]] = { mustprogress nosync readnone willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR26]] = { readonly willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR27]] = { nofree nosync nounwind } ; IS__CGSCC_NPM: attributes #[[ATTR28]] = { readnone willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR29]] = { nounwind } ; IS__CGSCC_NPM: attributes #[[ATTR30]] = { willreturn } ;.