xref: /llvm-project/llvm/test/Transforms/JumpThreading/freeze.ll (revision 07e34d2de565a88da2724d52cdcf47b4bca873db)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=jump-threading -S < %s | FileCheck %s
3
4declare i32 @f1()
5declare i32 @f2()
6declare void @f3()
7
8define i32 @test1(i1 %cond) {
9; CHECK-LABEL: @test1(
10; CHECK-NEXT:    br i1 [[COND:%.*]], label [[T2:%.*]], label [[F2:%.*]]
11; CHECK:       T2:
12; CHECK-NEXT:    [[V1:%.*]] = call i32 @f1()
13; CHECK-NEXT:    call void @f3()
14; CHECK-NEXT:    ret i32 [[V1]]
15; CHECK:       F2:
16; CHECK-NEXT:    [[V2:%.*]] = call i32 @f2()
17; CHECK-NEXT:    ret i32 [[V2]]
18;
19  br i1 %cond, label %T1, label %F1
20
21T1:
22  %v1 = call i32 @f1()
23  br label %Merge
24
25F1:
26  %v2 = call i32 @f2()
27  br label %Merge
28
29Merge:
30  %A = phi i1 [true, %T1], [false, %F1]
31  %B = phi i32 [%v1, %T1], [%v2, %F1]
32  %A.fr = freeze i1 %A
33  br i1 %A.fr, label %T2, label %F2
34
35T2:
36  call void @f3()
37  ret i32 %B
38
39F2:
40  ret i32 %B
41}
42
43define i32 @test1_cast(i1 %cond) {
44; CHECK-LABEL: @test1_cast(
45; CHECK-NEXT:    br i1 [[COND:%.*]], label [[T2:%.*]], label [[F2:%.*]]
46; CHECK:       T2:
47; CHECK-NEXT:    [[V1:%.*]] = call i32 @f1()
48; CHECK-NEXT:    call void @f3()
49; CHECK-NEXT:    ret i32 [[V1]]
50; CHECK:       F2:
51; CHECK-NEXT:    [[V2:%.*]] = call i32 @f2()
52; CHECK-NEXT:    [[A:%.*]] = trunc i32 0 to i1
53; CHECK-NEXT:    ret i32 [[V2]]
54;
55  br i1 %cond, label %T1, label %F1
56
57T1:
58  %v1 = call i32 @f1()
59  br label %Merge
60
61F1:
62  %v2 = call i32 @f2()
63  br label %Merge
64
65Merge:
66  %A0 = phi i32 [1, %T1], [0, %F1]
67  %B = phi i32 [%v1, %T1], [%v2, %F1]
68  %A = trunc i32 %A0 to i1
69  %A.fr = freeze i1 %A
70  br i1 %A.fr, label %T2, label %F2
71
72T2:
73  call void @f3()
74  ret i32 %B
75
76F2:
77  ret i32 %B
78}
79
80define i32 @test1_cast2(i1 %cond) {
81; CHECK-LABEL: @test1_cast2(
82; CHECK-NEXT:    br i1 [[COND:%.*]], label [[T2:%.*]], label [[F2:%.*]]
83; CHECK:       T2:
84; CHECK-NEXT:    [[V1:%.*]] = call i32 @f1()
85; CHECK-NEXT:    call void @f3()
86; CHECK-NEXT:    ret i32 [[V1]]
87; CHECK:       F2:
88; CHECK-NEXT:    [[V2:%.*]] = call i32 @f2()
89; CHECK-NEXT:    [[A0_FR:%.*]] = freeze i32 0
90; CHECK-NEXT:    ret i32 [[V2]]
91;
92  br i1 %cond, label %T1, label %F1
93
94T1:
95  %v1 = call i32 @f1()
96  br label %Merge
97
98F1:
99  %v2 = call i32 @f2()
100  br label %Merge
101
102Merge:
103  %A0 = phi i32 [1, %T1], [0, %F1]
104  %B = phi i32 [%v1, %T1], [%v2, %F1]
105  %A0.fr = freeze i32 %A0
106  %A.fr = trunc i32 %A0.fr to i1
107  br i1 %A.fr, label %T2, label %F2
108
109T2:
110  call void @f3()
111  ret i32 %B
112
113F2:
114  ret i32 %B
115}
116
117define i32 @test1_undef(i1 %cond) {
118; CHECK-LABEL: @test1_undef(
119; CHECK-NEXT:    br i1 [[COND:%.*]], label [[T2:%.*]], label [[F2:%.*]]
120; CHECK:       T2:
121; CHECK-NEXT:    [[V1:%.*]] = call i32 @f1()
122; CHECK-NEXT:    call void @f3()
123; CHECK-NEXT:    ret i32 [[V1]]
124; CHECK:       F2:
125; CHECK-NEXT:    [[V2:%.*]] = call i32 @f2()
126; CHECK-NEXT:    ret i32 [[V2]]
127;
128  br i1 %cond, label %T1, label %F1
129
130T1:
131  %v1 = call i32 @f1()
132  br label %Merge
133
134F1:
135  %v2 = call i32 @f2()
136  br label %Merge
137
138Merge:
139  %A = phi i1 [true, %T1], [undef, %F1]
140  %B = phi i32 [%v1, %T1], [%v2, %F1]
141  %A.fr = freeze i1 %A
142  br i1 %A.fr, label %T2, label %F2
143
144T2:
145  call void @f3()
146  ret i32 %B
147
148F2:
149  ret i32 %B
150}
151
152define i32 @test2(i1 %cond, i1 %cond2) {
153; CHECK-LABEL: @test2(
154; CHECK-NEXT:    br i1 [[COND:%.*]], label [[MERGE_THREAD:%.*]], label [[MERGE:%.*]]
155; CHECK:       Merge.thread:
156; CHECK-NEXT:    [[V1:%.*]] = call i32 @f1()
157; CHECK-NEXT:    br label [[T2:%.*]]
158; CHECK:       Merge:
159; CHECK-NEXT:    [[V2:%.*]] = call i32 @f2()
160; CHECK-NEXT:    [[A_FR:%.*]] = freeze i1 [[COND2:%.*]]
161; CHECK-NEXT:    br i1 [[A_FR]], label [[T2]], label [[F2:%.*]]
162; CHECK:       T2:
163; CHECK-NEXT:    [[B4:%.*]] = phi i32 [ [[V1]], [[MERGE_THREAD]] ], [ [[V2]], [[MERGE]] ]
164; CHECK-NEXT:    call void @f3()
165; CHECK-NEXT:    ret i32 [[B4]]
166; CHECK:       F2:
167; CHECK-NEXT:    ret i32 [[V2]]
168;
169  br i1 %cond, label %T1, label %F1
170
171T1:
172  %v1 = call i32 @f1()
173  br label %Merge
174
175F1:
176  %v2 = call i32 @f2()
177  br label %Merge
178
179Merge:
180  %A = phi i1 [true, %T1], [%cond2, %F1]
181  %B = phi i32 [%v1, %T1], [%v2, %F1]
182  %A.fr = freeze i1 %A
183  br i1 %A.fr, label %T2, label %F2
184
185T2:
186  call void @f3()
187  ret i32 %B
188
189F2:
190  ret i32 %B
191}
192
193define i32 @freeze_known_predicate(i1 %cond) {
194; CHECK-LABEL: @freeze_known_predicate(
195; CHECK-NEXT:  entry:
196; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE2:%.*]]
197; CHECK:       if:
198; CHECK-NEXT:    br label [[ELSE2]]
199; CHECK:       else2:
200; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ 1, [[IF]] ], [ 2, [[ENTRY:%.*]] ]
201; CHECK-NEXT:    ret i32 1
202;
203entry:
204  br i1 %cond, label %if, label %join
205
206if:
207  br label %join
208
209join:
210  %phi = phi i32 [ 1, %if ], [ 2, %entry ]
211  %cmp = icmp eq i32 %phi, 0
212  %cmp.fr = freeze i1 %cmp
213  br i1 %cmp.fr, label %if2, label %else2
214
215if2:
216  ret i32 0
217
218else2:
219  ret i32 1
220}
221
222define i32 @freeze_known_predicate_barrier(i1 %cond) {
223; CHECK-LABEL: @freeze_known_predicate_barrier(
224; CHECK-NEXT:  entry:
225; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE2:%.*]]
226; CHECK:       if:
227; CHECK-NEXT:    br label [[ELSE2]]
228; CHECK:       else2:
229; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ 1, [[IF]] ], [ 2, [[ENTRY:%.*]] ]
230; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[PHI]], 0
231; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @f1()
232; CHECK-NEXT:    ret i32 1
233;
234entry:
235  br i1 %cond, label %if, label %join
236
237if:
238  br label %join
239
240join:
241  %phi = phi i32 [ 1, %if ], [ 2, %entry ]
242  %cmp = icmp eq i32 %phi, 0
243  %cmp.fr = freeze i1 %cmp
244  call i32 @f1()
245  br i1 %cmp.fr, label %if2, label %else2
246
247if2:
248  ret i32 0
249
250else2:
251  ret i32 1
252}
253