Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / CorrelatedValuePropagation / urem-expansion.ll
blob8e276d010fdd1b476e9f087e1a50ff1d4beefd65
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s
4 declare void @llvm.assume(i1)
6 ; Divisor is constant. X's range is known
8 define i8 @constant.divisor.v3(i8 %x) {
9 ; CHECK-LABEL: @constant.divisor.v3(
10 ; CHECK-NEXT:    [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X:%.*]], 3
11 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X_UPPER]])
12 ; CHECK-NEXT:    ret i8 [[X]]
14   %cmp.x.upper = icmp ult i8 %x, 3
15   call void @llvm.assume(i1 %cmp.x.upper)
16   %rem = urem i8 %x, 3
17   ret i8 %rem
19 define i8 @constant.divisor.v4(i8 %x) {
20 ; CHECK-LABEL: @constant.divisor.v4(
21 ; CHECK-NEXT:    [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X:%.*]], 4
22 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X_UPPER]])
23 ; CHECK-NEXT:    [[X_FROZEN:%.*]] = freeze i8 [[X]]
24 ; CHECK-NEXT:    [[REM_UREM:%.*]] = sub nuw i8 [[X_FROZEN]], 3
25 ; CHECK-NEXT:    [[REM_CMP:%.*]] = icmp ult i8 [[X_FROZEN]], 3
26 ; CHECK-NEXT:    [[REM:%.*]] = select i1 [[REM_CMP]], i8 [[X_FROZEN]], i8 [[REM_UREM]]
27 ; CHECK-NEXT:    ret i8 [[REM]]
29   %cmp.x.upper = icmp ult i8 %x, 4
30   call void @llvm.assume(i1 %cmp.x.upper)
31   %rem = urem i8 %x, 3
32   ret i8 %rem
34 define i8 @constant.divisor.x.range.v4(ptr %x.ptr) {
35 ; CHECK-LABEL: @constant.divisor.x.range.v4(
36 ; CHECK-NEXT:    [[X:%.*]] = load i8, ptr [[X_PTR:%.*]], align 1, !range [[RNG0:![0-9]+]]
37 ; CHECK-NEXT:    [[X_FROZEN:%.*]] = freeze i8 [[X]]
38 ; CHECK-NEXT:    [[REM_UREM:%.*]] = sub nuw i8 [[X_FROZEN]], 3
39 ; CHECK-NEXT:    [[REM_CMP:%.*]] = icmp ult i8 [[X_FROZEN]], 3
40 ; CHECK-NEXT:    [[REM:%.*]] = select i1 [[REM_CMP]], i8 [[X_FROZEN]], i8 [[REM_UREM]]
41 ; CHECK-NEXT:    ret i8 [[REM]]
43   %x = load i8, ptr %x.ptr, !range !{ i8 0, i8 4 }
44   %rem = urem i8 %x, 3
45   ret i8 %rem
47 define i8 @constant.divisor.x.mask.v4(i8 %x) {
48 ; CHECK-LABEL: @constant.divisor.x.mask.v4(
49 ; CHECK-NEXT:    [[X_MASKED:%.*]] = and i8 [[X:%.*]], 3
50 ; CHECK-NEXT:    [[X_MASKED_FROZEN:%.*]] = freeze i8 [[X_MASKED]]
51 ; CHECK-NEXT:    [[REM_UREM:%.*]] = sub nuw i8 [[X_MASKED_FROZEN]], 3
52 ; CHECK-NEXT:    [[REM_CMP:%.*]] = icmp ult i8 [[X_MASKED_FROZEN]], 3
53 ; CHECK-NEXT:    [[REM:%.*]] = select i1 [[REM_CMP]], i8 [[X_MASKED_FROZEN]], i8 [[REM_UREM]]
54 ; CHECK-NEXT:    ret i8 [[REM]]
56   %x.masked = and i8 %x, 3
57   %rem = urem i8 %x.masked, 3
58   ret i8 %rem
60 define i8 @constant.divisor.v5(i8 %x) {
61 ; CHECK-LABEL: @constant.divisor.v5(
62 ; CHECK-NEXT:    [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X:%.*]], 5
63 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X_UPPER]])
64 ; CHECK-NEXT:    [[X_FROZEN:%.*]] = freeze i8 [[X]]
65 ; CHECK-NEXT:    [[REM_UREM:%.*]] = sub nuw i8 [[X_FROZEN]], 3
66 ; CHECK-NEXT:    [[REM_CMP:%.*]] = icmp ult i8 [[X_FROZEN]], 3
67 ; CHECK-NEXT:    [[REM:%.*]] = select i1 [[REM_CMP]], i8 [[X_FROZEN]], i8 [[REM_UREM]]
68 ; CHECK-NEXT:    ret i8 [[REM]]
70   %cmp.x.upper = icmp ult i8 %x, 5
71   call void @llvm.assume(i1 %cmp.x.upper)
72   %rem = urem i8 %x, 3
73   ret i8 %rem
75 define i8 @constant.divisor.v6(i8 %x) {
76 ; CHECK-LABEL: @constant.divisor.v6(
77 ; CHECK-NEXT:    [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X:%.*]], 6
78 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X_UPPER]])
79 ; CHECK-NEXT:    [[X_FROZEN:%.*]] = freeze i8 [[X]]
80 ; CHECK-NEXT:    [[REM_UREM:%.*]] = sub nuw i8 [[X_FROZEN]], 3
81 ; CHECK-NEXT:    [[REM_CMP:%.*]] = icmp ult i8 [[X_FROZEN]], 3
82 ; CHECK-NEXT:    [[REM:%.*]] = select i1 [[REM_CMP]], i8 [[X_FROZEN]], i8 [[REM_UREM]]
83 ; CHECK-NEXT:    ret i8 [[REM]]
85   %cmp.x.upper = icmp ult i8 %x, 6
86   call void @llvm.assume(i1 %cmp.x.upper)
87   %rem = urem i8 %x, 3
88   ret i8 %rem
90 define i8 @constant.divisor.v7(i8 %x) {
91 ; CHECK-LABEL: @constant.divisor.v7(
92 ; CHECK-NEXT:    [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X:%.*]], 7
93 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X_UPPER]])
94 ; CHECK-NEXT:    [[REM:%.*]] = urem i8 [[X]], 3
95 ; CHECK-NEXT:    ret i8 [[REM]]
97   %cmp.x.upper = icmp ult i8 %x, 7
98   call void @llvm.assume(i1 %cmp.x.upper)
99   %rem = urem i8 %x, 3
100   ret i8 %rem
103 define i8 @constant.divisor.v6to8(i8 %x) {
104 ; CHECK-LABEL: @constant.divisor.v6to8(
105 ; CHECK-NEXT:    [[CMP_X_LOWER:%.*]] = icmp uge i8 [[X:%.*]], 6
106 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X_LOWER]])
107 ; CHECK-NEXT:    [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X]], 9
108 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X_UPPER]])
109 ; CHECK-NEXT:    [[REM:%.*]] = urem i8 [[X]], 3
110 ; CHECK-NEXT:    ret i8 [[REM]]
112   %cmp.x.lower = icmp uge i8 %x, 6
113   call void @llvm.assume(i1 %cmp.x.lower)
114   %cmp.x.upper = icmp ult i8 %x, 9
115   call void @llvm.assume(i1 %cmp.x.upper)
116   %rem = urem i8 %x, 3
117   ret i8 %rem
120 define i8 @constant.divisor.v9to11(i8 %x) {
121 ; CHECK-LABEL: @constant.divisor.v9to11(
122 ; CHECK-NEXT:    [[CMP_X_LOWER:%.*]] = icmp uge i8 [[X:%.*]], 9
123 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X_LOWER]])
124 ; CHECK-NEXT:    [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X]], 12
125 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X_UPPER]])
126 ; CHECK-NEXT:    [[REM:%.*]] = urem i8 [[X]], 3
127 ; CHECK-NEXT:    ret i8 [[REM]]
129   %cmp.x.lower = icmp uge i8 %x, 9
130   call void @llvm.assume(i1 %cmp.x.lower)
131   %cmp.x.upper = icmp ult i8 %x, 12
132   call void @llvm.assume(i1 %cmp.x.upper)
133   %rem = urem i8 %x, 3
134   ret i8 %rem
137 define i8 @constant.divisor.v12to14(i8 %x) {
138 ; CHECK-LABEL: @constant.divisor.v12to14(
139 ; CHECK-NEXT:    [[CMP_X_LOWER:%.*]] = icmp uge i8 [[X:%.*]], 12
140 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X_LOWER]])
141 ; CHECK-NEXT:    [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X]], 15
142 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X_UPPER]])
143 ; CHECK-NEXT:    [[REM:%.*]] = urem i8 [[X]], 3
144 ; CHECK-NEXT:    ret i8 [[REM]]
146   %cmp.x.lower = icmp uge i8 %x, 12
147   call void @llvm.assume(i1 %cmp.x.lower)
148   %cmp.x.upper = icmp ult i8 %x, 15
149   call void @llvm.assume(i1 %cmp.x.upper)
150   %rem = urem i8 %x, 3
151   ret i8 %rem
154 define i8 @constant.divisor.v6to11(i8 %x) {
155 ; CHECK-LABEL: @constant.divisor.v6to11(
156 ; CHECK-NEXT:    [[CMP_X_LOWER:%.*]] = icmp uge i8 [[X:%.*]], 6
157 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X_LOWER]])
158 ; CHECK-NEXT:    [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X]], 12
159 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X_UPPER]])
160 ; CHECK-NEXT:    [[REM:%.*]] = urem i8 [[X]], 3
161 ; CHECK-NEXT:    ret i8 [[REM]]
163   %cmp.x.lower = icmp uge i8 %x, 6
164   call void @llvm.assume(i1 %cmp.x.lower)
165   %cmp.x.upper = icmp ult i8 %x, 12
166   call void @llvm.assume(i1 %cmp.x.upper)
167   %rem = urem i8 %x, 3
168   ret i8 %rem
171 ; Both are variable. Bounds are known
173 define i8 @variable.v3(i8 %x, i8 %y) {
174 ; CHECK-LABEL: @variable.v3(
175 ; CHECK-NEXT:    [[CMP_X:%.*]] = icmp ult i8 [[X:%.*]], 3
176 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X]])
177 ; CHECK-NEXT:    [[CMP_Y_LOWER:%.*]] = icmp uge i8 [[Y:%.*]], 3
178 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_Y_LOWER]])
179 ; CHECK-NEXT:    [[CMP_Y_UPPER:%.*]] = icmp ule i8 [[Y]], 4
180 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_Y_UPPER]])
181 ; CHECK-NEXT:    ret i8 [[X]]
183   %cmp.x = icmp ult i8 %x, 3
184   call void @llvm.assume(i1 %cmp.x)
185   %cmp.y.lower = icmp uge i8 %y, 3
186   call void @llvm.assume(i1 %cmp.y.lower)
187   %cmp.y.upper = icmp ule i8 %y, 4
188   call void @llvm.assume(i1 %cmp.y.upper)
189   %rem = urem i8 %x, %y
190   ret i8 %rem
192 define i8 @variable.v4(i8 %x, i8 %y) {
193 ; CHECK-LABEL: @variable.v4(
194 ; CHECK-NEXT:    [[CMP_X:%.*]] = icmp ult i8 [[X:%.*]], 4
195 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X]])
196 ; CHECK-NEXT:    [[CMP_Y_LOWER:%.*]] = icmp uge i8 [[Y:%.*]], 3
197 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_Y_LOWER]])
198 ; CHECK-NEXT:    [[CMP_Y_UPPER:%.*]] = icmp ule i8 [[Y]], 4
199 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_Y_UPPER]])
200 ; CHECK-NEXT:    [[X_FROZEN:%.*]] = freeze i8 [[X]]
201 ; CHECK-NEXT:    [[Y_FROZEN:%.*]] = freeze i8 [[Y]]
202 ; CHECK-NEXT:    [[REM_UREM:%.*]] = sub nuw i8 [[X_FROZEN]], [[Y_FROZEN]]
203 ; CHECK-NEXT:    [[REM_CMP:%.*]] = icmp ult i8 [[X_FROZEN]], [[Y_FROZEN]]
204 ; CHECK-NEXT:    [[REM:%.*]] = select i1 [[REM_CMP]], i8 [[X_FROZEN]], i8 [[REM_UREM]]
205 ; CHECK-NEXT:    ret i8 [[REM]]
207   %cmp.x = icmp ult i8 %x, 4
208   call void @llvm.assume(i1 %cmp.x)
209   %cmp.y.lower = icmp uge i8 %y, 3
210   call void @llvm.assume(i1 %cmp.y.lower)
211   %cmp.y.upper = icmp ule i8 %y, 4
212   call void @llvm.assume(i1 %cmp.y.upper)
213   %rem = urem i8 %x, %y
214   ret i8 %rem
216 define i8 @variable.v4.range(ptr %x.ptr, ptr %y.ptr) {
217 ; CHECK-LABEL: @variable.v4.range(
218 ; CHECK-NEXT:    [[X:%.*]] = load i8, ptr [[X_PTR:%.*]], align 1, !range [[RNG0]]
219 ; CHECK-NEXT:    [[Y:%.*]] = load i8, ptr [[Y_PTR:%.*]], align 1, !range [[RNG1:![0-9]+]]
220 ; CHECK-NEXT:    [[X_FROZEN:%.*]] = freeze i8 [[X]]
221 ; CHECK-NEXT:    [[Y_FROZEN:%.*]] = freeze i8 [[Y]]
222 ; CHECK-NEXT:    [[REM_UREM:%.*]] = sub nuw i8 [[X_FROZEN]], [[Y_FROZEN]]
223 ; CHECK-NEXT:    [[REM_CMP:%.*]] = icmp ult i8 [[X_FROZEN]], [[Y_FROZEN]]
224 ; CHECK-NEXT:    [[REM:%.*]] = select i1 [[REM_CMP]], i8 [[X_FROZEN]], i8 [[REM_UREM]]
225 ; CHECK-NEXT:    ret i8 [[REM]]
227   %x = load i8, ptr %x.ptr, !range !{ i8 0, i8 4 }
228   %y = load i8, ptr %y.ptr, !range !{ i8 3, i8 5 }
229   %rem = urem i8 %x, %y
230   ret i8 %rem
232 define i8 @variable.v5(i8 %x, i8 %y) {
233 ; CHECK-LABEL: @variable.v5(
234 ; CHECK-NEXT:    [[CMP_X:%.*]] = icmp ult i8 [[X:%.*]], 5
235 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X]])
236 ; CHECK-NEXT:    [[CMP_Y_LOWER:%.*]] = icmp uge i8 [[Y:%.*]], 3
237 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_Y_LOWER]])
238 ; CHECK-NEXT:    [[CMP_Y_UPPER:%.*]] = icmp ule i8 [[Y]], 4
239 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_Y_UPPER]])
240 ; CHECK-NEXT:    [[X_FROZEN:%.*]] = freeze i8 [[X]]
241 ; CHECK-NEXT:    [[Y_FROZEN:%.*]] = freeze i8 [[Y]]
242 ; CHECK-NEXT:    [[REM_UREM:%.*]] = sub nuw i8 [[X_FROZEN]], [[Y_FROZEN]]
243 ; CHECK-NEXT:    [[REM_CMP:%.*]] = icmp ult i8 [[X_FROZEN]], [[Y_FROZEN]]
244 ; CHECK-NEXT:    [[REM:%.*]] = select i1 [[REM_CMP]], i8 [[X_FROZEN]], i8 [[REM_UREM]]
245 ; CHECK-NEXT:    ret i8 [[REM]]
247   %cmp.x = icmp ult i8 %x, 5
248   call void @llvm.assume(i1 %cmp.x)
249   %cmp.y.lower = icmp uge i8 %y, 3
250   call void @llvm.assume(i1 %cmp.y.lower)
251   %cmp.y.upper = icmp ule i8 %y, 4
252   call void @llvm.assume(i1 %cmp.y.upper)
253   %rem = urem i8 %x, %y
254   ret i8 %rem
256 define i8 @variable.v6(i8 %x, i8 %y) {
257 ; CHECK-LABEL: @variable.v6(
258 ; CHECK-NEXT:    [[CMP_X:%.*]] = icmp ult i8 [[X:%.*]], 6
259 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X]])
260 ; CHECK-NEXT:    [[CMP_Y_LOWER:%.*]] = icmp uge i8 [[Y:%.*]], 3
261 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_Y_LOWER]])
262 ; CHECK-NEXT:    [[CMP_Y_UPPER:%.*]] = icmp ule i8 [[Y]], 4
263 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_Y_UPPER]])
264 ; CHECK-NEXT:    [[X_FROZEN:%.*]] = freeze i8 [[X]]
265 ; CHECK-NEXT:    [[Y_FROZEN:%.*]] = freeze i8 [[Y]]
266 ; CHECK-NEXT:    [[REM_UREM:%.*]] = sub nuw i8 [[X_FROZEN]], [[Y_FROZEN]]
267 ; CHECK-NEXT:    [[REM_CMP:%.*]] = icmp ult i8 [[X_FROZEN]], [[Y_FROZEN]]
268 ; CHECK-NEXT:    [[REM:%.*]] = select i1 [[REM_CMP]], i8 [[X_FROZEN]], i8 [[REM_UREM]]
269 ; CHECK-NEXT:    ret i8 [[REM]]
271   %cmp.x = icmp ult i8 %x, 6
272   call void @llvm.assume(i1 %cmp.x)
273   %cmp.y.lower = icmp uge i8 %y, 3
274   call void @llvm.assume(i1 %cmp.y.lower)
275   %cmp.y.upper = icmp ule i8 %y, 4
276   call void @llvm.assume(i1 %cmp.y.upper)
277   %rem = urem i8 %x, %y
278   ret i8 %rem
280 define i8 @variable.v7(i8 %x, i8 %y) {
281 ; CHECK-LABEL: @variable.v7(
282 ; CHECK-NEXT:    [[CMP_X:%.*]] = icmp ult i8 [[X:%.*]], 7
283 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X]])
284 ; CHECK-NEXT:    [[CMP_Y_LOWER:%.*]] = icmp uge i8 [[Y:%.*]], 3
285 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_Y_LOWER]])
286 ; CHECK-NEXT:    [[CMP_Y_UPPER:%.*]] = icmp ule i8 [[Y]], 4
287 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_Y_UPPER]])
288 ; CHECK-NEXT:    [[REM:%.*]] = urem i8 [[X]], [[Y]]
289 ; CHECK-NEXT:    ret i8 [[REM]]
291   %cmp.x = icmp ult i8 %x, 7
292   call void @llvm.assume(i1 %cmp.x)
293   %cmp.y.lower = icmp uge i8 %y, 3
294   call void @llvm.assume(i1 %cmp.y.lower)
295   %cmp.y.upper = icmp ule i8 %y, 4
296   call void @llvm.assume(i1 %cmp.y.upper)
297   %rem = urem i8 %x, %y
298   ret i8 %rem
301 define i8 @variable.v6to8.v3to4(i8 %x, i8 %y) {
302 ; CHECK-LABEL: @variable.v6to8.v3to4(
303 ; CHECK-NEXT:    [[CMP_X_LOWER:%.*]] = icmp uge i8 [[X:%.*]], 6
304 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X_LOWER]])
305 ; CHECK-NEXT:    [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X]], 8
306 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X_UPPER]])
307 ; CHECK-NEXT:    [[CMP_Y_LOWER:%.*]] = icmp uge i8 [[Y:%.*]], 3
308 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_Y_LOWER]])
309 ; CHECK-NEXT:    [[CMP_Y_UPPER:%.*]] = icmp ule i8 [[Y]], 4
310 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_Y_UPPER]])
311 ; CHECK-NEXT:    [[REM:%.*]] = urem i8 [[X]], [[Y]]
312 ; CHECK-NEXT:    ret i8 [[REM]]
314   %cmp.x.lower = icmp uge i8 %x, 6
315   call void @llvm.assume(i1 %cmp.x.lower)
316   %cmp.x.upper = icmp ult i8 %x, 8
317   call void @llvm.assume(i1 %cmp.x.upper)
318   %cmp.y.lower = icmp uge i8 %y, 3
319   call void @llvm.assume(i1 %cmp.y.lower)
320   %cmp.y.upper = icmp ule i8 %y, 4
321   call void @llvm.assume(i1 %cmp.y.upper)
322   %rem = urem i8 %x, %y
323   ret i8 %rem
326 ; Constant divisor
328 define i8 @large.divisor.v0(i8 %x) {
329 ; CHECK-LABEL: @large.divisor.v0(
330 ; CHECK-NEXT:    [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X:%.*]], 127
331 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X_UPPER]])
332 ; CHECK-NEXT:    ret i8 [[X]]
334   %cmp.x.upper = icmp ult i8 %x, 127
335   call void @llvm.assume(i1 %cmp.x.upper)
336   %rem = urem i8 %x, 127
337   ret i8 %rem
339 define i8 @large.divisor.v1(i8 %x) {
340 ; CHECK-LABEL: @large.divisor.v1(
341 ; CHECK-NEXT:    [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X:%.*]], -128
342 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X_UPPER]])
343 ; CHECK-NEXT:    [[X_FROZEN:%.*]] = freeze i8 [[X]]
344 ; CHECK-NEXT:    [[REM_UREM:%.*]] = sub nuw i8 [[X_FROZEN]], 127
345 ; CHECK-NEXT:    [[REM_CMP:%.*]] = icmp ult i8 [[X_FROZEN]], 127
346 ; CHECK-NEXT:    [[REM:%.*]] = select i1 [[REM_CMP]], i8 [[X_FROZEN]], i8 [[REM_UREM]]
347 ; CHECK-NEXT:    ret i8 [[REM]]
349   %cmp.x.upper = icmp ult i8 %x, 128
350   call void @llvm.assume(i1 %cmp.x.upper)
351   %rem = urem i8 %x, 127
352   ret i8 %rem
354 define i8 @large.divisor.v1.range(ptr %x.ptr) {
355 ; CHECK-LABEL: @large.divisor.v1.range(
356 ; CHECK-NEXT:    [[X:%.*]] = load i8, ptr [[X_PTR:%.*]], align 1, !range [[RNG2:![0-9]+]]
357 ; CHECK-NEXT:    [[X_FROZEN:%.*]] = freeze i8 [[X]]
358 ; CHECK-NEXT:    [[REM_UREM:%.*]] = sub nuw i8 [[X_FROZEN]], 127
359 ; CHECK-NEXT:    [[REM_CMP:%.*]] = icmp ult i8 [[X_FROZEN]], 127
360 ; CHECK-NEXT:    [[REM:%.*]] = select i1 [[REM_CMP]], i8 [[X_FROZEN]], i8 [[REM_UREM]]
361 ; CHECK-NEXT:    ret i8 [[REM]]
363   %x = load i8, ptr %x.ptr, !range !{ i8 0, i8 128 }
364   %rem = urem i8 %x, 127
365   ret i8 %rem
367 define i8 @large.divisor.v2.unbound.x(i8 %x) {
368 ; CHECK-LABEL: @large.divisor.v2.unbound.x(
369 ; CHECK-NEXT:    [[REM:%.*]] = urem i8 [[X:%.*]], 127
370 ; CHECK-NEXT:    ret i8 [[REM]]
372   %rem = urem i8 %x, 127
373   ret i8 %rem
376 define i8 @large.divisor.with.overflow.v0(i8 %x) {
377 ; CHECK-LABEL: @large.divisor.with.overflow.v0(
378 ; CHECK-NEXT:    [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X:%.*]], -128
379 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X_UPPER]])
380 ; CHECK-NEXT:    ret i8 [[X]]
382   %cmp.x.upper = icmp ult i8 %x, 128
383   call void @llvm.assume(i1 %cmp.x.upper)
384   %rem = urem i8 %x, 128
385   ret i8 %rem
387 define i8 @large.divisor.with.overflow.v1(i8 %x) {
388 ; CHECK-LABEL: @large.divisor.with.overflow.v1(
389 ; CHECK-NEXT:    [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X:%.*]], -127
390 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X_UPPER]])
391 ; CHECK-NEXT:    [[X_FROZEN:%.*]] = freeze i8 [[X]]
392 ; CHECK-NEXT:    [[REM_UREM:%.*]] = sub nuw i8 [[X_FROZEN]], -128
393 ; CHECK-NEXT:    [[REM_CMP:%.*]] = icmp ult i8 [[X_FROZEN]], -128
394 ; CHECK-NEXT:    [[REM:%.*]] = select i1 [[REM_CMP]], i8 [[X_FROZEN]], i8 [[REM_UREM]]
395 ; CHECK-NEXT:    ret i8 [[REM]]
397   %cmp.x.upper = icmp ult i8 %x, 129
398   call void @llvm.assume(i1 %cmp.x.upper)
399   %rem = urem i8 %x, 128
400   ret i8 %rem
402 define i8 @large.divisor.with.overflow.v1.range(ptr %x.ptr) {
403 ; CHECK-LABEL: @large.divisor.with.overflow.v1.range(
404 ; CHECK-NEXT:    [[X:%.*]] = load i8, ptr [[X_PTR:%.*]], align 1, !range [[RNG3:![0-9]+]]
405 ; CHECK-NEXT:    [[X_FROZEN:%.*]] = freeze i8 [[X]]
406 ; CHECK-NEXT:    [[REM_UREM:%.*]] = sub nuw i8 [[X_FROZEN]], -128
407 ; CHECK-NEXT:    [[REM_CMP:%.*]] = icmp ult i8 [[X_FROZEN]], -128
408 ; CHECK-NEXT:    [[REM:%.*]] = select i1 [[REM_CMP]], i8 [[X_FROZEN]], i8 [[REM_UREM]]
409 ; CHECK-NEXT:    ret i8 [[REM]]
411   %x = load i8, ptr %x.ptr, !range !{ i8 0, i8 129 }
412   %rem = urem i8 %x, 128
413   ret i8 %rem
415 define i8 @large.divisor.with.overflow.v2.unbound.x(i8 %x) {
416 ; CHECK-LABEL: @large.divisor.with.overflow.v2.unbound.x(
417 ; CHECK-NEXT:    [[X_FROZEN:%.*]] = freeze i8 [[X:%.*]]
418 ; CHECK-NEXT:    [[REM_UREM:%.*]] = sub nuw i8 [[X_FROZEN]], -128
419 ; CHECK-NEXT:    [[REM_CMP:%.*]] = icmp ult i8 [[X_FROZEN]], -128
420 ; CHECK-NEXT:    [[REM:%.*]] = select i1 [[REM_CMP]], i8 [[X_FROZEN]], i8 [[REM_UREM]]
421 ; CHECK-NEXT:    ret i8 [[REM]]
423   %rem = urem i8 %x, 128
424   ret i8 %rem
427 define i1 @icmp_after_expansion(i8 noundef %x) {
428 ; CHECK-LABEL: @icmp_after_expansion(
429 ; CHECK-NEXT:    [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X:%.*]], 6
430 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X_UPPER]])
431 ; CHECK-NEXT:    [[REM_UREM:%.*]] = sub nuw i8 [[X]], 3
432 ; CHECK-NEXT:    [[REM_CMP:%.*]] = icmp ult i8 [[X]], 3
433 ; CHECK-NEXT:    [[REM:%.*]] = select i1 [[REM_CMP]], i8 [[X]], i8 [[REM_UREM]]
434 ; CHECK-NEXT:    ret i1 false
436   %cmp.x.upper = icmp ult i8 %x, 6
437   call void @llvm.assume(i1 %cmp.x.upper)
438   %rem = urem i8 %x, 3
439   %cmp = icmp eq i8 %rem, 3
440   ret i1 %cmp
443 define i8 @known_uge(i8 noundef %x) {
444 ; CHECK-LABEL: @known_uge(
445 ; CHECK-NEXT:    [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X:%.*]], 6
446 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X_UPPER]])
447 ; CHECK-NEXT:    [[CMP_X_LOWER:%.*]] = icmp uge i8 [[X]], 3
448 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_X_LOWER]])
449 ; CHECK-NEXT:    [[REM:%.*]] = sub nuw i8 [[X]], 3
450 ; CHECK-NEXT:    ret i8 [[REM]]
452   %cmp.x.upper = icmp ult i8 %x, 6
453   call void @llvm.assume(i1 %cmp.x.upper)
454   %cmp.x.lower = icmp uge i8 %x, 3
455   call void @llvm.assume(i1 %cmp.x.lower)
456   %rem = urem i8 %x, 3
457   ret i8 %rem