Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / BPF / sink-min-max.ll
blob5ee080839985d2036e3bbf919248bb0450ab0937
1 ; RUN: opt --bpf-check-and-opt-ir -S -mtriple=bpf-pc-linux %s | FileCheck %s
3 ; Test plan:
4 ; @test1: x <  umin(i64 a, i64 b)
5 ; @test2: x <  umax(i64 a, i64 b)
6 ; @test3: x >= umin(i64 a, i64 b)
7 ; @test4: x >= umax(i64 a, i64 b)
8 ; @test5: umin(i64 a, i64 b) >= x
9 ; @test6: x <  smin(i64 a, i64 b)
10 ; @test7: x <  umin(i32 a, i32 b)
11 ; @test8: x <  zext i64 umin(i32 a, i32 b)
12 ; @test9: x <  sext i64 umin(i32 a, i32 b)
13 ; @test10: check that umin belonging to the same loop is not touched
14 ; @test11: check that nested loops are processed
16 define i32 @test1(i64 %a, i64 %b, i64 %x) {
17 entry:
18   %min = tail call i64 @llvm.umin.i64(i64 %a, i64 %b)
19   br label %loop
20 loop:
21   %cmp = icmp ult i64 %x, %min
22   br i1 %cmp, label %loop, label %ret
23 ret: ret i32 0
26 ; CHECK:       @test1
27 ; CHECK-NEXT:  entry:
28 ; CHECK-NEXT:    br label %loop
29 ; CHECK-EMPTY:
30 ; CHECK-NEXT:  loop:
31 ; CHECK-NEXT:    %0 = icmp ult i64 %x, %a
32 ; CHECK-NEXT:    %1 = icmp ult i64 %x, %b
33 ; CHECK-NEXT:    %2 = select i1 %0, i1 %1, i1 false
34 ; CHECK-NEXT:    br i1 %2, label %loop, label %ret
36 define i32 @test2(i64 %a, i64 %b, i64 %x) {
37 entry:
38   %max = tail call i64 @llvm.umax.i64(i64 %a, i64 %b)
39   br label %loop
40 loop:
41   %cmp = icmp ult i64 %x, %max
42   br i1 %cmp, label %loop, label %ret
43 ret: ret i32 0
46 ; CHECK:       @test2
47 ; CHECK-NEXT:  entry:
48 ; CHECK-NEXT:    br label %loop
49 ; CHECK-EMPTY:
50 ; CHECK-NEXT:  loop:
51 ; CHECK-NEXT:    %0 = icmp ult i64 %x, %a
52 ; CHECK-NEXT:    %1 = icmp ult i64 %x, %b
53 ; CHECK-NEXT:    %2 = select i1 %0, i1 true, i1 %1
54 ; CHECK-NEXT:    br i1 %2, label %loop, label %ret
56 define i32 @test3(i64 %a, i64 %b, i64 %x) {
57 entry:
58   %min = tail call i64 @llvm.umin.i64(i64 %a, i64 %b)
59   br label %loop
60 loop:
61   %cmp = icmp uge i64 %x, %min
62   br i1 %cmp, label %loop, label %ret
63 ret: ret i32 0
66 ; CHECK:       @test3
67 ; CHECK-NEXT:  entry:
68 ; CHECK-NEXT:    br label %loop
69 ; CHECK-EMPTY:
70 ; CHECK-NEXT:  loop:
71 ; CHECK-NEXT:    %0 = icmp uge i64 %x, %a
72 ; CHECK-NEXT:    %1 = icmp uge i64 %x, %b
73 ; CHECK-NEXT:    %2 = select i1 %0, i1 true, i1 %1
74 ; CHECK-NEXT:    br i1 %2, label %loop, label %ret
76 define i32 @test4(i64 %a, i64 %b, i64 %x) {
77 entry:
78   %max = tail call i64 @llvm.umax.i64(i64 %a, i64 %b)
79   br label %loop
80 loop:
81   %cmp = icmp uge i64 %x, %max
82   br i1 %cmp, label %loop, label %ret
83 ret: ret i32 0
86 ; CHECK:       @test4
87 ; CHECK-NEXT:  entry:
88 ; CHECK-NEXT:    br label %loop
89 ; CHECK-EMPTY:
90 ; CHECK-NEXT:  loop:
91 ; CHECK-NEXT:    %0 = icmp uge i64 %x, %a
92 ; CHECK-NEXT:    %1 = icmp uge i64 %x, %b
93 ; CHECK-NEXT:    %2 = select i1 %0, i1 %1, i1 false
94 ; CHECK-NEXT:    br i1 %2, label %loop, label %ret
96 define i32 @test5(i64 %a, i64 %b, i64 %x) {
97 entry:
98   %min = tail call i64 @llvm.umin.i64(i64 %a, i64 %b)
99   br label %loop
100 loop:
101   %cmp = icmp uge i64 %min, %x
102   br i1 %cmp, label %loop, label %ret
103 ret: ret i32 0
106 ; CHECK:       @test5
107 ; CHECK-NEXT:  entry:
108 ; CHECK-NEXT:    br label %loop
109 ; CHECK-EMPTY:
110 ; CHECK-NEXT:  loop:
111 ; CHECK:         %0 = icmp ule i64 %x, %a
112 ; CHECK-NEXT:    %1 = icmp ule i64 %x, %b
113 ; CHECK-NEXT:    %2 = select i1 %0, i1 %1, i1 false
114 ; CHECK-NEXT:    br i1 %2, label %loop, label %ret
116 define i32 @test6(i64 %a, i64 %b, i64 %x) {
117 entry:
118   %min = tail call i64 @llvm.smin.i64(i64 %a, i64 %b)
119   br label %loop
120 loop:
121   %cmp = icmp slt i64 %x, %min
122   br i1 %cmp, label %loop, label %ret
123 ret: ret i32 0
126 ; CHECK:       @test6
127 ; CHECK-NEXT:  entry:
128 ; CHECK-NEXT:    br label %loop
129 ; CHECK-EMPTY:
130 ; CHECK-NEXT:  loop:
131 ; CHECK:         %0 = icmp slt i64 %x, %a
132 ; CHECK-NEXT:    %1 = icmp slt i64 %x, %b
133 ; CHECK-NEXT:    %2 = select i1 %0, i1 %1, i1 false
134 ; CHECK-NEXT:    br i1 %2, label %loop, label %ret
136 define i32 @test7(i32 %a, i32 %b, i32 %x) {
137 entry:
138   %min = tail call i32 @llvm.umin.i32(i32 %a, i32 %b)
139   br label %loop
140 loop:
141   %cmp = icmp ult i32 %x, %min
142   br i1 %cmp, label %loop, label %ret
143 ret: ret i32 0
146 ; CHECK:       @test7
147 ; CHECK-NEXT:  entry:
148 ; CHECK-NEXT:    br label %loop
149 ; CHECK-EMPTY:
150 ; CHECK-NEXT:  loop:
151 ; CHECK:         %0 = icmp ult i32 %x, %a
152 ; CHECK-NEXT:    %1 = icmp ult i32 %x, %b
153 ; CHECK-NEXT:    %2 = select i1 %0, i1 %1, i1 false
154 ; CHECK-NEXT:    br i1 %2, label %loop, label %ret
156 define i32 @test8(i32 %a, i32 %b, i64 %x) {
157 entry:
158   %min = tail call i32 @llvm.umin.i32(i32 %a, i32 %b)
159   br label %loop
160 loop:
161   %ext = zext i32 %min to i64
162   %cmp = icmp ult i64 %x, %ext
163   br i1 %cmp, label %loop, label %ret
164 ret: ret i32 0
167 ; CHECK:       @test8
168 ; CHECK-NEXT:  entry:
169 ; CHECK-NEXT:    br label %loop
170 ; CHECK-EMPTY:
171 ; CHECK-NEXT:  loop:
172 ; CHECK-NEXT:    %0 = zext i32 %a to i64
173 ; CHECK-NEXT:    %1 = zext i32 %b to i64
174 ; CHECK-NEXT:    %2 = icmp ult i64 %x, %0
175 ; CHECK-NEXT:    %3 = icmp ult i64 %x, %1
176 ; CHECK-NEXT:    %4 = select i1 %2, i1 %3, i1 false
177 ; CHECK-NEXT:    br i1 %4, label %loop, label %ret
179 define i32 @test9(i32 %a, i32 %b, i64 %x) {
180 entry:
181   %min = tail call i32 @llvm.umin.i32(i32 %a, i32 %b)
182   br label %loop
183 loop:
184   %ext = sext i32 %min to i64
185   %cmp = icmp ult i64 %x, %ext
186   br i1 %cmp, label %loop, label %ret
187 ret: ret i32 0
190 ; CHECK:       @test9
191 ; CHECK-NEXT:  entry:
192 ; CHECK-NEXT:    br label %loop
193 ; CHECK-EMPTY:
194 ; CHECK-NEXT:  loop:
195 ; CHECK-NEXT:    %0 = sext i32 %a to i64
196 ; CHECK-NEXT:    %1 = sext i32 %b to i64
197 ; CHECK-NEXT:    %2 = icmp ult i64 %x, %0
198 ; CHECK-NEXT:    %3 = icmp ult i64 %x, %1
199 ; CHECK-NEXT:    %4 = select i1 %2, i1 %3, i1 false
200 ; CHECK-NEXT:    br i1 %4, label %loop, label %ret
202 ; umin within the loop body is unchanged
203 define i32 @test10(i64 %a, i64 %b, i64 %x) {
204 entry:
205   br label %loop
206 loop:
207   %min = tail call i64 @llvm.umin.i64(i64 %a, i64 %b)
208   %cmp = icmp ult i64 %x, %min
209   br i1 %cmp, label %loop, label %ret
210 ret: ret i32 0
213 ; CHECK:       @test10
214 ; CHECK-NEXT:  entry:
215 ; CHECK-NEXT:    br label %loop
216 ; CHECK-EMPTY:
217 ; CHECK-NEXT:  loop:
218 ; CHECK-NEXT:    %min = tail call i64 @llvm.umin.i64(i64 %a, i64 %b)
219 ; CHECK-NEXT:    %cmp = icmp ult i64 %x, %min
220 ; CHECK-NEXT:    br i1 %cmp, label %loop, label %ret
222 ; umin from outer loop body is processed
223 define i32 @test11(i64 %a, i64 %b, i64 %x) {
224 entry:
225   br label %loop
227 loop:
228   %min = tail call i64 @llvm.umin.i64(i64 %a, i64 %b)
229   br label %nested.loop
230 nested.loop:
231   %cmp = icmp ult i64 %x, %min
232   br i1 %cmp, label %nested.loop, label %loop
234 ret: ret i32 0
237 ; CHECK:       @test11
238 ; CHECK-NEXT:  entry:
239 ; CHECK-NEXT:    br label %loop
240 ; CHECK-EMPTY:
241 ; CHECK-NEXT:  loop:
242 ; CHECK-NEXT:    br label %nested.loop
243 ; CHECK-EMPTY:
244 ; CHECK-NEXT:  nested.loop:
245 ; CHECK-NEXT:    %0 = icmp ult i64 %x, %a
246 ; CHECK-NEXT:    %1 = icmp ult i64 %x, %b
247 ; CHECK-NEXT:    %2 = select i1 %0, i1 %1, i1 false
248 ; CHECK-NEXT:    br i1 %2, label %nested.loop, label %loop
250 declare i64 @llvm.umin.i64(i64, i64)
251 declare i64 @llvm.smin.i64(i64, i64)
252 declare i64 @llvm.umax.i64(i64, i64)
253 declare i64 @llvm.smax.i64(i64, i64)
255 declare i32 @llvm.umin.i32(i32, i32)
256 declare i32 @llvm.smin.i32(i32, i32)
257 declare i32 @llvm.umax.i32(i32, i32)
258 declare i32 @llvm.smax.i32(i32, i32)