1 ; RUN: opt -function-attrs -S %s | FileCheck %s
3 define void @mustprogress_readnone() mustprogress {
4 ; CHECK: Function Attrs: {{.*}} noreturn {{.*}} readnone willreturn
5 ; CHECK-NEXT: define void @mustprogress_readnone()
14 define i32 @mustprogress_load(i32* %ptr) mustprogress {
15 ; CHECK: Function Attrs: {{.*}} readonly willreturn
16 ; CHECK-NEXT: define i32 @mustprogress_load(
22 %r = load i32, i32* %ptr
26 define void @mustprogress_store(i32* %ptr) mustprogress {
27 ; CHECK-NOT: Function Attrs: {{.*}} willreturn
28 ; CHECK: define void @mustprogress_store(
34 store i32 0, i32* %ptr
38 declare void @unknown_fn()
40 define void @mustprogress_call_unknown_fn() mustprogress {
41 ; CHECK-NOT: Function Attrs: {{.*}} willreturn
42 ; CHECK: define void @mustprogress_call_unknown_fn(
44 call void @unknown_fn()
48 define i32 @mustprogress_call_known_functions(i32* %ptr) mustprogress {
49 ; CHECK: Function Attrs: {{.*}} readonly willreturn
50 ; CHECK-NEXT: define i32 @mustprogress_call_known_functions(
52 call void @mustprogress_readnone()
53 %r = call i32 @mustprogress_load(i32* %ptr)
57 declare i32 @__gxx_personality_v0(...)
59 define i64 @mustprogress_mayunwind() mustprogress personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
60 ; CHECK: Function Attrs: {{.*}} readnone willreturn
61 ; CHECK-NEXT: define i64 @mustprogress_mayunwind(
63 %a = invoke i64 @fn_noread()
64 to label %A unwind label %B
69 %val = landingpad { i8*, i32 }
74 ; Function without loops or non-willreturn calls will return.
75 define void @willreturn_no_loop(i1 %c, i32* %p) {
76 ; CHECK: Function Attrs: mustprogress willreturn
77 ; CHECK-NEXT: define void @willreturn_no_loop(
79 br i1 %c, label %if, label %else
82 load atomic i32, i32* %p seq_cst, align 4
83 call void @fn_willreturn()
87 store atomic i32 0, i32* %p seq_cst, align 4
94 ; Calls a function that is not guaranteed to return, not willreturn.
95 define void @willreturn_non_returning_function(i1 %c, i32* %p) {
96 ; CHECK-NOT: Function Attrs: {{.*}}willreturn
97 ; CHECK: define void @willreturn_non_returning_function(
99 call void @unknown_fn()
103 ; Infinite loop without mustprogress, will not return.
104 define void @willreturn_loop() {
105 ; CHECK-NOT: Function Attrs: {{.*}}willreturn
106 ; CHECK: define void @willreturn_loop(
114 ; Finite loop. Could be willreturn but not detected.
116 define void @willreturn_finite_loop() {
117 ; CHECK-NOT: Function Attrs: {{.*}}willreturn
118 ; CHECK: define void @willreturn_finite_loop(
124 %i = phi i32 [ 0, %entry], [ %i.inc, %loop ]
125 %i.inc = add nuw i32 %i, 1
126 %c = icmp ne i32 %i.inc, 100
127 br i1 %c, label %loop, label %end
133 ; Infinite recursion without mustprogress, will not return.
134 define void @willreturn_recursion() {
135 ; CHECK-NOT: Function Attrs: {{.*}}willreturn
136 ; CHECK: define void @willreturn_recursion(
138 tail call void @willreturn_recursion()
142 ; Irreducible infinite loop, will not return.
143 define void @willreturn_irreducible(i1 %c) {
144 ; CHECK-NOT: Function Attrs: {{.*}}willreturn
145 ; CHECK: define void @willreturn_irreducible(
147 br i1 %c, label %bb1, label %bb2
156 define linkonce i32 @square(i32) {
157 ; CHECK-NOT: Function Attrs: {{.*}}willreturn
158 ; CHECK: define linkonce i32 @square(
159 %2 = mul nsw i32 %0, %0
163 declare i64 @fn_noread() readnone
164 declare void @fn_willreturn() willreturn