[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / FunctionAttrs / willreturn.ll
blob0465311926acf92c25eac1f87e4e556fbfd15d71
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()
7 entry:
8   br label %while.body
10 while.body:
11   br label %while.body
14 define i32 @mustprogress_load(i32* %ptr) mustprogress {
15 ; CHECK:      Function Attrs: {{.*}} readonly willreturn
16 ; CHECK-NEXT: define i32 @mustprogress_load(
18 entry:
19   br label %while.body
21 while.body:
22   %r = load i32, i32* %ptr
23   br label %while.body
26 define void @mustprogress_store(i32* %ptr) mustprogress {
27 ; CHECK-NOT: Function Attrs: {{.*}} willreturn
28 ; CHECK: define void @mustprogress_store(
30 entry:
31   br label %while.body
33 while.body:
34   store i32 0, i32* %ptr
35   br label %while.body
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()
45   ret void
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)
54   ret i32 %r
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
66   ret i64 10
69   %val = landingpad { i8*, i32 }
70            catch i8* null
71   ret i64 0
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
81 if:
82   load atomic i32, i32* %p seq_cst, align 4
83   call void @fn_willreturn()
84   br label %end
86 else:
87   store atomic i32 0, i32* %p seq_cst, align 4
88   br label %end
90 end:
91   ret void
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()
100   ret void
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(
108   br label %loop
110 loop:
111   br label %loop
114 ; Finite loop. Could be willreturn but not detected.
115 ; FIXME
116 define void @willreturn_finite_loop() {
117 ; CHECK-NOT: Function Attrs: {{.*}}willreturn
118 ; CHECK: define void @willreturn_finite_loop(
120 entry:
121   br label %loop
123 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
129 end:
130   ret void
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()
139   ret void
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
149 bb1:
150   br label %bb2
152 bb2:
153   br label %bb1
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
160     ret i32 %2
163 declare i64 @fn_noread() readnone
164 declare void @fn_willreturn() willreturn