[TTI] getTypeBasedIntrinsicInstrCost - add basic handling for strided load/store...
[llvm-project.git] / llvm / test / CodeGen / X86 / fold-loop-of-urem.ll
blobc1beb7c803b2b3ed0d521e019794699ea26a0a61
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
4 declare void @use.i32(i32)
5 declare void @use.2xi64(<2 x i64>)
6 declare void @do_stuff0()
7 declare void @do_stuff1()
8 declare i1 @get.i1()
9 declare i32 @get.i32()
11 define void @simple_urem_to_sel(i32 %N, i32 %rem_amt) nounwind {
12 ; CHECK-LABEL: simple_urem_to_sel:
13 ; CHECK:       # %bb.0: # %entry
14 ; CHECK-NEXT:    testl %edi, %edi
15 ; CHECK-NEXT:    je .LBB0_4
16 ; CHECK-NEXT:  # %bb.1: # %for.body.preheader
17 ; CHECK-NEXT:    pushq %rbp
18 ; CHECK-NEXT:    pushq %r15
19 ; CHECK-NEXT:    pushq %r14
20 ; CHECK-NEXT:    pushq %r12
21 ; CHECK-NEXT:    pushq %rbx
22 ; CHECK-NEXT:    movl %esi, %ebx
23 ; CHECK-NEXT:    movl %edi, %ebp
24 ; CHECK-NEXT:    xorl %r15d, %r15d
25 ; CHECK-NEXT:    xorl %r14d, %r14d
26 ; CHECK-NEXT:    xorl %r12d, %r12d
27 ; CHECK-NEXT:    .p2align 4
28 ; CHECK-NEXT:  .LBB0_2: # %for.body
29 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
30 ; CHECK-NEXT:    movl %r14d, %edi
31 ; CHECK-NEXT:    callq use.i32@PLT
32 ; CHECK-NEXT:    incl %r14d
33 ; CHECK-NEXT:    cmpl %ebx, %r14d
34 ; CHECK-NEXT:    cmovel %r15d, %r14d
35 ; CHECK-NEXT:    incl %r12d
36 ; CHECK-NEXT:    cmpl %r12d, %ebp
37 ; CHECK-NEXT:    jne .LBB0_2
38 ; CHECK-NEXT:  # %bb.3:
39 ; CHECK-NEXT:    popq %rbx
40 ; CHECK-NEXT:    popq %r12
41 ; CHECK-NEXT:    popq %r14
42 ; CHECK-NEXT:    popq %r15
43 ; CHECK-NEXT:    popq %rbp
44 ; CHECK-NEXT:  .LBB0_4: # %for.cond.cleanup
45 ; CHECK-NEXT:    retq
46 entry:
47   %cmp3.not = icmp eq i32 %N, 0
48   br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
50 for.cond.cleanup:
51   ret void
53 for.body:
54   %i.04 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
55   %rem = urem i32 %i.04, %rem_amt
56   tail call void @use.i32(i32 %rem)
57   %inc = add nuw i32 %i.04, 1
58   %exitcond.not = icmp eq i32 %inc, %N
59   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
62 define void @simple_urem_to_sel_fail_not_in_loop(i32 %N, i32 %rem_amt) nounwind {
63 ; CHECK-LABEL: simple_urem_to_sel_fail_not_in_loop:
64 ; CHECK:       # %bb.0: # %entry
65 ; CHECK-NEXT:    pushq %rbp
66 ; CHECK-NEXT:    pushq %r14
67 ; CHECK-NEXT:    pushq %rbx
68 ; CHECK-NEXT:    movl %esi, %ebx
69 ; CHECK-NEXT:    testl %edi, %edi
70 ; CHECK-NEXT:    je .LBB1_1
71 ; CHECK-NEXT:  # %bb.3: # %for.body.preheader
72 ; CHECK-NEXT:    movl %edi, %r14d
73 ; CHECK-NEXT:    xorl %ebp, %ebp
74 ; CHECK-NEXT:    .p2align 4
75 ; CHECK-NEXT:  .LBB1_4: # %for.body
76 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
77 ; CHECK-NEXT:    movl %ebp, %edi
78 ; CHECK-NEXT:    callq use.i32@PLT
79 ; CHECK-NEXT:    incl %ebp
80 ; CHECK-NEXT:    cmpl %ebp, %r14d
81 ; CHECK-NEXT:    jne .LBB1_4
82 ; CHECK-NEXT:    jmp .LBB1_2
83 ; CHECK-NEXT:  .LBB1_1:
84 ; CHECK-NEXT:    xorl %ebp, %ebp
85 ; CHECK-NEXT:  .LBB1_2: # %for.cond.cleanup
86 ; CHECK-NEXT:    movl %ebp, %eax
87 ; CHECK-NEXT:    xorl %edx, %edx
88 ; CHECK-NEXT:    divl %ebx
89 ; CHECK-NEXT:    movl %edx, %edi
90 ; CHECK-NEXT:    popq %rbx
91 ; CHECK-NEXT:    popq %r14
92 ; CHECK-NEXT:    popq %rbp
93 ; CHECK-NEXT:    jmp use.i32@PLT # TAILCALL
94 entry:
95   %cmp3.not = icmp eq i32 %N, 0
96   br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
98 for.cond.cleanup:
99   %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
100   %rem = urem i32 %i.05, %rem_amt
101   tail call void @use.i32(i32 %rem)
102   ret void
104 for.body:
105   %i.04 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
106   tail call void @use.i32(i32 %i.04)
107   %inc = add nuw i32 %i.04, 1
108   %exitcond.not = icmp eq i32 %inc, %N
109   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
112 define void @simple_urem_to_sel_inner_loop(i32 %N, i32 %M) nounwind {
113 ; CHECK-LABEL: simple_urem_to_sel_inner_loop:
114 ; CHECK:       # %bb.0: # %entry
115 ; CHECK-NEXT:    pushq %rbp
116 ; CHECK-NEXT:    pushq %r15
117 ; CHECK-NEXT:    pushq %r14
118 ; CHECK-NEXT:    pushq %r13
119 ; CHECK-NEXT:    pushq %r12
120 ; CHECK-NEXT:    pushq %rbx
121 ; CHECK-NEXT:    pushq %rax
122 ; CHECK-NEXT:    movl %esi, %r12d
123 ; CHECK-NEXT:    movl %edi, %ebp
124 ; CHECK-NEXT:    callq get.i32@PLT
125 ; CHECK-NEXT:    testl %ebp, %ebp
126 ; CHECK-NEXT:    je .LBB2_6
127 ; CHECK-NEXT:  # %bb.1: # %for.body.preheader
128 ; CHECK-NEXT:    movl %eax, %r14d
129 ; CHECK-NEXT:    xorl %r15d, %r15d
130 ; CHECK-NEXT:    xorl %r13d, %r13d
131 ; CHECK-NEXT:    jmp .LBB2_2
132 ; CHECK-NEXT:    .p2align 4
133 ; CHECK-NEXT:  .LBB2_5: # %for.inner.cond.cleanup
134 ; CHECK-NEXT:    # in Loop: Header=BB2_2 Depth=1
135 ; CHECK-NEXT:    incl %r15d
136 ; CHECK-NEXT:    cmpl %r14d, %r15d
137 ; CHECK-NEXT:    movl $0, %eax
138 ; CHECK-NEXT:    cmovel %eax, %r15d
139 ; CHECK-NEXT:    incl %r13d
140 ; CHECK-NEXT:    cmpl %ebp, %r13d
141 ; CHECK-NEXT:    je .LBB2_6
142 ; CHECK-NEXT:  .LBB2_2: # %for.body
143 ; CHECK-NEXT:    # =>This Loop Header: Depth=1
144 ; CHECK-NEXT:    # Child Loop BB2_4 Depth 2
145 ; CHECK-NEXT:    testl %r12d, %r12d
146 ; CHECK-NEXT:    je .LBB2_5
147 ; CHECK-NEXT:  # %bb.3: # %for.inner.body.preheader
148 ; CHECK-NEXT:    # in Loop: Header=BB2_2 Depth=1
149 ; CHECK-NEXT:    movl %r12d, %ebx
150 ; CHECK-NEXT:    .p2align 4
151 ; CHECK-NEXT:  .LBB2_4: # %for.inner.body
152 ; CHECK-NEXT:    # Parent Loop BB2_2 Depth=1
153 ; CHECK-NEXT:    # => This Inner Loop Header: Depth=2
154 ; CHECK-NEXT:    movl %r15d, %edi
155 ; CHECK-NEXT:    callq use.i32@PLT
156 ; CHECK-NEXT:    decl %ebx
157 ; CHECK-NEXT:    jne .LBB2_4
158 ; CHECK-NEXT:    jmp .LBB2_5
159 ; CHECK-NEXT:  .LBB2_6: # %for.cond.cleanup
160 ; CHECK-NEXT:    addq $8, %rsp
161 ; CHECK-NEXT:    popq %rbx
162 ; CHECK-NEXT:    popq %r12
163 ; CHECK-NEXT:    popq %r13
164 ; CHECK-NEXT:    popq %r14
165 ; CHECK-NEXT:    popq %r15
166 ; CHECK-NEXT:    popq %rbp
167 ; CHECK-NEXT:    retq
168 entry:
169   %rem_amt = call i32 @get.i32()
170   %cmp3.not = icmp eq i32 %N, 0
171   br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
173 for.cond.cleanup:
174   ret void
176 for.body:
177   %i.04 = phi i32 [ %inc, %for.inner.cond.cleanup ], [ 0, %entry ]
179   %cmp_inner = icmp eq i32 %M, 0
180   br i1 %cmp_inner, label %for.inner.cond.cleanup, label %for.inner.body
182 for.inner.body:
183   %j = phi i32 [ %inc_inner, %for.inner.body ], [ 0, %for.body ]
184   %rem = urem i32 %i.04, %rem_amt
185   tail call void @use.i32(i32 %rem)
186   %inc_inner = add nuw i32 %j, 1
187   %exitcond_inner = icmp eq i32 %inc_inner, %M
188   br i1 %exitcond_inner, label %for.inner.cond.cleanup, label %for.inner.body
190 for.inner.cond.cleanup:
191   %inc = add nuw i32 %i.04, 1
192   %exitcond.not = icmp eq i32 %inc, %N
193   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
196 define void @simple_urem_to_sel_inner_loop_fail_not_invariant(i32 %N, i32 %M) nounwind {
197 ; CHECK-LABEL: simple_urem_to_sel_inner_loop_fail_not_invariant:
198 ; CHECK:       # %bb.0: # %entry
199 ; CHECK-NEXT:    testl %edi, %edi
200 ; CHECK-NEXT:    je .LBB3_7
201 ; CHECK-NEXT:  # %bb.1: # %for.body.preheader
202 ; CHECK-NEXT:    pushq %rbp
203 ; CHECK-NEXT:    pushq %r15
204 ; CHECK-NEXT:    pushq %r14
205 ; CHECK-NEXT:    pushq %r12
206 ; CHECK-NEXT:    pushq %rbx
207 ; CHECK-NEXT:    movl %esi, %ebx
208 ; CHECK-NEXT:    movl %edi, %ebp
209 ; CHECK-NEXT:    xorl %r14d, %r14d
210 ; CHECK-NEXT:    jmp .LBB3_2
211 ; CHECK-NEXT:    .p2align 4
212 ; CHECK-NEXT:  .LBB3_5: # %for.inner.cond.cleanup
213 ; CHECK-NEXT:    # in Loop: Header=BB3_2 Depth=1
214 ; CHECK-NEXT:    incl %r14d
215 ; CHECK-NEXT:    cmpl %ebp, %r14d
216 ; CHECK-NEXT:    je .LBB3_6
217 ; CHECK-NEXT:  .LBB3_2: # %for.body
218 ; CHECK-NEXT:    # =>This Loop Header: Depth=1
219 ; CHECK-NEXT:    # Child Loop BB3_4 Depth 2
220 ; CHECK-NEXT:    callq get.i32@PLT
221 ; CHECK-NEXT:    testl %ebx, %ebx
222 ; CHECK-NEXT:    je .LBB3_5
223 ; CHECK-NEXT:  # %bb.3: # %for.inner.body.preheader
224 ; CHECK-NEXT:    # in Loop: Header=BB3_2 Depth=1
225 ; CHECK-NEXT:    movl %eax, %r15d
226 ; CHECK-NEXT:    movl %ebx, %r12d
227 ; CHECK-NEXT:    .p2align 4
228 ; CHECK-NEXT:  .LBB3_4: # %for.inner.body
229 ; CHECK-NEXT:    # Parent Loop BB3_2 Depth=1
230 ; CHECK-NEXT:    # => This Inner Loop Header: Depth=2
231 ; CHECK-NEXT:    movl %r14d, %eax
232 ; CHECK-NEXT:    xorl %edx, %edx
233 ; CHECK-NEXT:    divl %r15d
234 ; CHECK-NEXT:    movl %edx, %edi
235 ; CHECK-NEXT:    callq use.i32@PLT
236 ; CHECK-NEXT:    decl %r12d
237 ; CHECK-NEXT:    jne .LBB3_4
238 ; CHECK-NEXT:    jmp .LBB3_5
239 ; CHECK-NEXT:  .LBB3_6:
240 ; CHECK-NEXT:    popq %rbx
241 ; CHECK-NEXT:    popq %r12
242 ; CHECK-NEXT:    popq %r14
243 ; CHECK-NEXT:    popq %r15
244 ; CHECK-NEXT:    popq %rbp
245 ; CHECK-NEXT:  .LBB3_7: # %for.cond.cleanup
246 ; CHECK-NEXT:    retq
247 entry:
248   %cmp3.not = icmp eq i32 %N, 0
249   br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
251 for.cond.cleanup:
252   ret void
254 for.body:
255   %i.04 = phi i32 [ %inc, %for.inner.cond.cleanup ], [ 0, %entry ]
256   %rem_amt = call i32 @get.i32()
257   %cmp_inner = icmp eq i32 %M, 0
258   br i1 %cmp_inner, label %for.inner.cond.cleanup, label %for.inner.body
260 for.inner.body:
261   %j = phi i32 [ %inc_inner, %for.inner.body ], [ 0, %for.body ]
262   %rem = urem i32 %i.04, %rem_amt
263   tail call void @use.i32(i32 %rem)
264   %inc_inner = add nuw i32 %j, 1
265   %exitcond_inner = icmp eq i32 %inc_inner, %M
266   br i1 %exitcond_inner, label %for.inner.cond.cleanup, label %for.inner.body
268 for.inner.cond.cleanup:
269   %inc = add nuw i32 %i.04, 1
270   %exitcond.not = icmp eq i32 %inc, %N
271   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
274 define void @simple_urem_to_sel_nested2(i32 %N, i32 %rem_amt) nounwind {
275 ; CHECK-LABEL: simple_urem_to_sel_nested2:
276 ; CHECK:       # %bb.0: # %entry
277 ; CHECK-NEXT:    testl %edi, %edi
278 ; CHECK-NEXT:    je .LBB4_8
279 ; CHECK-NEXT:  # %bb.1: # %for.body.preheader
280 ; CHECK-NEXT:    pushq %rbp
281 ; CHECK-NEXT:    pushq %r15
282 ; CHECK-NEXT:    pushq %r14
283 ; CHECK-NEXT:    pushq %r12
284 ; CHECK-NEXT:    pushq %rbx
285 ; CHECK-NEXT:    movl %esi, %ebx
286 ; CHECK-NEXT:    movl %edi, %ebp
287 ; CHECK-NEXT:    xorl %r15d, %r15d
288 ; CHECK-NEXT:    xorl %r14d, %r14d
289 ; CHECK-NEXT:    xorl %r12d, %r12d
290 ; CHECK-NEXT:    jmp .LBB4_2
291 ; CHECK-NEXT:    .p2align 4
292 ; CHECK-NEXT:  .LBB4_5: # %for.body1
293 ; CHECK-NEXT:    # in Loop: Header=BB4_2 Depth=1
294 ; CHECK-NEXT:    movl %r14d, %edi
295 ; CHECK-NEXT:    callq use.i32@PLT
296 ; CHECK-NEXT:  .LBB4_6: # %for.body.tail
297 ; CHECK-NEXT:    # in Loop: Header=BB4_2 Depth=1
298 ; CHECK-NEXT:    incl %r14d
299 ; CHECK-NEXT:    cmpl %ebx, %r14d
300 ; CHECK-NEXT:    cmovel %r15d, %r14d
301 ; CHECK-NEXT:    incl %r12d
302 ; CHECK-NEXT:    cmpl %r12d, %ebp
303 ; CHECK-NEXT:    je .LBB4_7
304 ; CHECK-NEXT:  .LBB4_2: # %for.body
305 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
306 ; CHECK-NEXT:    callq get.i1@PLT
307 ; CHECK-NEXT:    testb $1, %al
308 ; CHECK-NEXT:    je .LBB4_6
309 ; CHECK-NEXT:  # %bb.3: # %for.body0
310 ; CHECK-NEXT:    # in Loop: Header=BB4_2 Depth=1
311 ; CHECK-NEXT:    callq get.i1@PLT
312 ; CHECK-NEXT:    testb $1, %al
313 ; CHECK-NEXT:    jne .LBB4_5
314 ; CHECK-NEXT:  # %bb.4: # %for.body2
315 ; CHECK-NEXT:    # in Loop: Header=BB4_2 Depth=1
316 ; CHECK-NEXT:    callq get.i1@PLT
317 ; CHECK-NEXT:    testb $1, %al
318 ; CHECK-NEXT:    jne .LBB4_5
319 ; CHECK-NEXT:    jmp .LBB4_6
320 ; CHECK-NEXT:  .LBB4_7:
321 ; CHECK-NEXT:    popq %rbx
322 ; CHECK-NEXT:    popq %r12
323 ; CHECK-NEXT:    popq %r14
324 ; CHECK-NEXT:    popq %r15
325 ; CHECK-NEXT:    popq %rbp
326 ; CHECK-NEXT:  .LBB4_8: # %for.cond.cleanup
327 ; CHECK-NEXT:    retq
328 entry:
329   %cmp3.not = icmp eq i32 %N, 0
330   br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
332 for.cond.cleanup:
333   ret void
335 for.body:
336   %i.04 = phi i32 [ %inc, %for.body.tail ], [ 0, %entry ]
337   %cond0 = call i1 @get.i1()
338   br i1 %cond0, label %for.body0, label %for.body.tail
339 for.body0:
340   %cond1 = call i1 @get.i1()
341   br i1 %cond1, label %for.body1, label %for.body2
342 for.body2:
343   %cond2 = call i1 @get.i1()
344   br i1 %cond2, label %for.body1, label %for.body.tail
345 for.body1:
346   %rem = urem i32 %i.04, %rem_amt
347   tail call void @use.i32(i32 %rem)
348   br label %for.body.tail
349 for.body.tail:
350   %inc = add nuw i32 %i.04, 1
351   %exitcond.not = icmp eq i32 %inc, %N
352   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
355 define void @simple_urem_fail_bad_incr3(i32 %N, i32 %rem_amt) nounwind {
356 ; CHECK-LABEL: simple_urem_fail_bad_incr3:
357 ; CHECK:       # %bb.0: # %entry
358 ; CHECK-NEXT:    testl %edi, %edi
359 ; CHECK-NEXT:    je .LBB5_9
360 ; CHECK-NEXT:  # %bb.1:
361 ; CHECK-NEXT:    pushq %rbp
362 ; CHECK-NEXT:    pushq %r14
363 ; CHECK-NEXT:    pushq %rbx
364 ; CHECK-NEXT:    movl %esi, %ebx
365 ; CHECK-NEXT:    jmp .LBB5_2
366 ; CHECK-NEXT:    .p2align 4
367 ; CHECK-NEXT:  .LBB5_6: # %for.body1
368 ; CHECK-NEXT:    # in Loop: Header=BB5_2 Depth=1
369 ; CHECK-NEXT:    movl %ebp, %eax
370 ; CHECK-NEXT:    xorl %edx, %edx
371 ; CHECK-NEXT:    divl %ebx
372 ; CHECK-NEXT:    movl %edx, %edi
373 ; CHECK-NEXT:    callq use.i32@PLT
374 ; CHECK-NEXT:  .LBB5_7: # %for.body.tail
375 ; CHECK-NEXT:    # in Loop: Header=BB5_2 Depth=1
376 ; CHECK-NEXT:    callq get.i1@PLT
377 ; CHECK-NEXT:    testb $1, %al
378 ; CHECK-NEXT:    jne .LBB5_8
379 ; CHECK-NEXT:  .LBB5_2: # %for.body
380 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
381 ; CHECK-NEXT:    callq get.i1@PLT
382 ; CHECK-NEXT:    testb $1, %al
383 ; CHECK-NEXT:    je .LBB5_5
384 ; CHECK-NEXT:  # %bb.3: # %for.body0
385 ; CHECK-NEXT:    # in Loop: Header=BB5_2 Depth=1
386 ; CHECK-NEXT:    callq get.i1@PLT
387 ; CHECK-NEXT:    movl %eax, %r14d
388 ; CHECK-NEXT:    callq get.i32@PLT
389 ; CHECK-NEXT:    testb $1, %r14b
390 ; CHECK-NEXT:    je .LBB5_7
391 ; CHECK-NEXT:  # %bb.4: # in Loop: Header=BB5_2 Depth=1
392 ; CHECK-NEXT:    movl %eax, %ebp
393 ; CHECK-NEXT:    incl %ebp
394 ; CHECK-NEXT:    jmp .LBB5_6
395 ; CHECK-NEXT:    .p2align 4
396 ; CHECK-NEXT:  .LBB5_5: # %for.body2
397 ; CHECK-NEXT:    # in Loop: Header=BB5_2 Depth=1
398 ; CHECK-NEXT:    xorl %ebp, %ebp
399 ; CHECK-NEXT:    callq get.i1@PLT
400 ; CHECK-NEXT:    testb $1, %al
401 ; CHECK-NEXT:    jne .LBB5_6
402 ; CHECK-NEXT:    jmp .LBB5_7
403 ; CHECK-NEXT:  .LBB5_8:
404 ; CHECK-NEXT:    popq %rbx
405 ; CHECK-NEXT:    popq %r14
406 ; CHECK-NEXT:    popq %rbp
407 ; CHECK-NEXT:  .LBB5_9: # %for.cond.cleanup
408 ; CHECK-NEXT:    retq
409 entry:
410   %cmp3.not = icmp eq i32 %N, 0
411   br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
413 for.cond.cleanup:
414   ret void
416 for.body:
417   %cond0 = call i1 @get.i1()
418   br i1 %cond0, label %for.body0, label %for.body2
419 for.body0:
420   %cond1 = call i1 @get.i1()
421   %val = call i32 @get.i32()
422   %inc = add nuw i32 %val, 1
423   br i1 %cond1, label %for.body1, label %for.body.tail
424 for.body2:
425   %cond2 = call i1 @get.i1()
426   br i1 %cond2, label %for.body1, label %for.body.tail
427 for.body1:
428   %i.04 = phi i32 [ %inc, %for.body0], [ 0, %for.body2 ]
429   %rem = urem i32 %i.04, %rem_amt
430   tail call void @use.i32(i32 %rem)
431   br label %for.body.tail
432 for.body.tail:
433   %exitcond.not = call i1 @get.i1()
434   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
437 define void @simple_urem_to_sel_vec(<2 x i64> %rem_amt) nounwind {
438 ; CHECK-LABEL: simple_urem_to_sel_vec:
439 ; CHECK:       # %bb.0: # %entry
440 ; CHECK-NEXT:    subq $56, %rsp
441 ; CHECK-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
442 ; CHECK-NEXT:    pxor %xmm1, %xmm1
443 ; CHECK-NEXT:    pxor %xmm0, %xmm0
444 ; CHECK-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
445 ; CHECK-NEXT:    .p2align 4
446 ; CHECK-NEXT:  .LBB6_1: # %for.body
447 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
448 ; CHECK-NEXT:    movdqa %xmm1, (%rsp) # 16-byte Spill
449 ; CHECK-NEXT:    movdqa %xmm1, %xmm0
450 ; CHECK-NEXT:    callq use.2xi64@PLT
451 ; CHECK-NEXT:    pcmpeqd %xmm1, %xmm1
452 ; CHECK-NEXT:    movdqa (%rsp), %xmm2 # 16-byte Reload
453 ; CHECK-NEXT:    psubq %xmm1, %xmm2
454 ; CHECK-NEXT:    movdqa %xmm2, %xmm0
455 ; CHECK-NEXT:    movdqa %xmm2, %xmm3
456 ; CHECK-NEXT:    pcmpeqd {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload
457 ; CHECK-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[1,0,3,2]
458 ; CHECK-NEXT:    pand %xmm0, %xmm2
459 ; CHECK-NEXT:    pandn %xmm3, %xmm2
460 ; CHECK-NEXT:    movdqa %xmm2, (%rsp) # 16-byte Spill
461 ; CHECK-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
462 ; CHECK-NEXT:    psubq %xmm1, %xmm0
463 ; CHECK-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
464 ; CHECK-NEXT:    callq get.i1@PLT
465 ; CHECK-NEXT:    testb $1, %al
466 ; CHECK-NEXT:    movdqa (%rsp), %xmm1 # 16-byte Reload
467 ; CHECK-NEXT:    je .LBB6_1
468 ; CHECK-NEXT:  # %bb.2: # %for.cond.cleanup
469 ; CHECK-NEXT:    addq $56, %rsp
470 ; CHECK-NEXT:    retq
471 entry:
472   br label %for.body
474 for.cond.cleanup:
475   ret void
477 for.body:
478   %i.04 = phi <2 x i64> [ %inc, %for.body ], [ zeroinitializer, %entry ]
479   %rem = urem <2 x i64> %i.04, %rem_amt
480   tail call void @use.2xi64(<2 x i64> %rem)
481   %inc = add nuw <2 x i64> %i.04, <i64 1, i64 1>
482   %exitcond.not = call i1 @get.i1()
483   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
486 define void @simple_urem_fail_bad_incr(i32 %N, i32 %rem_amt) nounwind {
487 ; CHECK-LABEL: simple_urem_fail_bad_incr:
488 ; CHECK:       # %bb.0: # %entry
489 ; CHECK-NEXT:    testl %edi, %edi
490 ; CHECK-NEXT:    je .LBB7_6
491 ; CHECK-NEXT:  # %bb.1: # %for.body.preheader
492 ; CHECK-NEXT:    pushq %rbp
493 ; CHECK-NEXT:    pushq %r14
494 ; CHECK-NEXT:    pushq %rbx
495 ; CHECK-NEXT:    movl %esi, %ebx
496 ; CHECK-NEXT:    movl %edi, %ebp
497 ; CHECK-NEXT:    xorl %r14d, %r14d
498 ; CHECK-NEXT:    jmp .LBB7_2
499 ; CHECK-NEXT:    .p2align 4
500 ; CHECK-NEXT:  .LBB7_4: # %for.body.tail
501 ; CHECK-NEXT:    # in Loop: Header=BB7_2 Depth=1
502 ; CHECK-NEXT:    movl %r14d, %eax
503 ; CHECK-NEXT:    xorl %edx, %edx
504 ; CHECK-NEXT:    divl %ebx
505 ; CHECK-NEXT:    movl %edx, %edi
506 ; CHECK-NEXT:    callq use.i32@PLT
507 ; CHECK-NEXT:    incl %r14d
508 ; CHECK-NEXT:    cmpl %ebp, %r14d
509 ; CHECK-NEXT:    je .LBB7_5
510 ; CHECK-NEXT:  .LBB7_2: # %for.body
511 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
512 ; CHECK-NEXT:    callq get.i1@PLT
513 ; CHECK-NEXT:    testb $1, %al
514 ; CHECK-NEXT:    je .LBB7_4
515 ; CHECK-NEXT:  # %bb.3: # %for.body0
516 ; CHECK-NEXT:    # in Loop: Header=BB7_2 Depth=1
517 ; CHECK-NEXT:    callq get.i32@PLT
518 ; CHECK-NEXT:    movl %eax, %r14d
519 ; CHECK-NEXT:    jmp .LBB7_4
520 ; CHECK-NEXT:  .LBB7_5:
521 ; CHECK-NEXT:    popq %rbx
522 ; CHECK-NEXT:    popq %r14
523 ; CHECK-NEXT:    popq %rbp
524 ; CHECK-NEXT:  .LBB7_6: # %for.cond.cleanup
525 ; CHECK-NEXT:    retq
526 entry:
527   %cmp3.not = icmp eq i32 %N, 0
528   br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
530 for.cond.cleanup:
531   ret void
533 for.body:
534   %i.03 = phi i32 [ %inc, %for.body.tail ], [ 0, %entry ]
535   %cond0 = call i1 @get.i1()
536   br i1 %cond0, label %for.body0, label %for.body.tail
537 for.body0:
538   %some_val = call i32 @get.i32()
539   br label %for.body.tail
541 for.body.tail:
542   %i.04 = phi i32 [ %i.03, %for.body ], [ %some_val, %for.body0 ]
543   %rem = urem i32 %i.04, %rem_amt
544   tail call void @use.i32(i32 %rem)
545   %inc = add nuw i32 %i.04, 1
546   %exitcond.not = icmp eq i32 %inc, %N
547   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
550 define void @simple_urem_to_sel_second_acc(i32 %N, i32 %rem_amt) nounwind {
551 ; CHECK-LABEL: simple_urem_to_sel_second_acc:
552 ; CHECK:       # %bb.0: # %entry
553 ; CHECK-NEXT:    cmpl $2, %edi
554 ; CHECK-NEXT:    jb .LBB8_4
555 ; CHECK-NEXT:  # %bb.1: # %for.body.preheader
556 ; CHECK-NEXT:    pushq %rbp
557 ; CHECK-NEXT:    pushq %r15
558 ; CHECK-NEXT:    pushq %r14
559 ; CHECK-NEXT:    pushq %r13
560 ; CHECK-NEXT:    pushq %r12
561 ; CHECK-NEXT:    pushq %rbx
562 ; CHECK-NEXT:    pushq %rax
563 ; CHECK-NEXT:    movl %esi, %ebx
564 ; CHECK-NEXT:    movl %edi, %ebp
565 ; CHECK-NEXT:    movl $1, %r15d
566 ; CHECK-NEXT:    xorl %r12d, %r12d
567 ; CHECK-NEXT:    xorl %r14d, %r14d
568 ; CHECK-NEXT:    xorl %r13d, %r13d
569 ; CHECK-NEXT:    .p2align 4
570 ; CHECK-NEXT:  .LBB8_2: # %for.body
571 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
572 ; CHECK-NEXT:    movl %r14d, %edi
573 ; CHECK-NEXT:    callq use.i32@PLT
574 ; CHECK-NEXT:    incl %r14d
575 ; CHECK-NEXT:    cmpl %ebx, %r14d
576 ; CHECK-NEXT:    cmovel %r12d, %r14d
577 ; CHECK-NEXT:    incl %r13d
578 ; CHECK-NEXT:    addl $2, %r15d
579 ; CHECK-NEXT:    cmpl %ebp, %r15d
580 ; CHECK-NEXT:    jbe .LBB8_2
581 ; CHECK-NEXT:  # %bb.3:
582 ; CHECK-NEXT:    addq $8, %rsp
583 ; CHECK-NEXT:    popq %rbx
584 ; CHECK-NEXT:    popq %r12
585 ; CHECK-NEXT:    popq %r13
586 ; CHECK-NEXT:    popq %r14
587 ; CHECK-NEXT:    popq %r15
588 ; CHECK-NEXT:    popq %rbp
589 ; CHECK-NEXT:  .LBB8_4: # %for.cond.cleanup
590 ; CHECK-NEXT:    retq
591 entry:
592   %cmp3.not = icmp ult i32 %N, 2
593   br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
595 for.cond.cleanup:
596   ret void
598 for.body:
599   %i.04 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
600   %i.05 = phi i32 [ %inc2, %for.body ], [ 1, %entry ]
601   %rem = urem i32 %i.04, %rem_amt
602   tail call void @use.i32(i32 %rem)
603   %inc = add nuw i32 %i.04, 1
604   %inc2 = add nuw i32 %i.05, 2
605   %exitcond.not = icmp ugt i32 %inc2, %N
606   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
609 define void @simple_urem_fail_srem(i32 %N, i32 %rem_amt) nounwind {
610 ; CHECK-LABEL: simple_urem_fail_srem:
611 ; CHECK:       # %bb.0: # %entry
612 ; CHECK-NEXT:    testl %edi, %edi
613 ; CHECK-NEXT:    je .LBB9_4
614 ; CHECK-NEXT:  # %bb.1: # %for.body.preheader
615 ; CHECK-NEXT:    pushq %rbp
616 ; CHECK-NEXT:    pushq %r14
617 ; CHECK-NEXT:    pushq %rbx
618 ; CHECK-NEXT:    movl %esi, %ebx
619 ; CHECK-NEXT:    movl %edi, %ebp
620 ; CHECK-NEXT:    xorl %r14d, %r14d
621 ; CHECK-NEXT:    .p2align 4
622 ; CHECK-NEXT:  .LBB9_2: # %for.body
623 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
624 ; CHECK-NEXT:    movl %r14d, %eax
625 ; CHECK-NEXT:    cltd
626 ; CHECK-NEXT:    idivl %ebx
627 ; CHECK-NEXT:    movl %edx, %edi
628 ; CHECK-NEXT:    callq use.i32@PLT
629 ; CHECK-NEXT:    incl %r14d
630 ; CHECK-NEXT:    cmpl %r14d, %ebp
631 ; CHECK-NEXT:    jne .LBB9_2
632 ; CHECK-NEXT:  # %bb.3:
633 ; CHECK-NEXT:    popq %rbx
634 ; CHECK-NEXT:    popq %r14
635 ; CHECK-NEXT:    popq %rbp
636 ; CHECK-NEXT:  .LBB9_4: # %for.cond.cleanup
637 ; CHECK-NEXT:    retq
638 entry:
639   %cmp3.not = icmp eq i32 %N, 0
640   br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
642 for.cond.cleanup:
643   ret void
645 for.body:
646   %i.04 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
647   %rem = srem i32 %i.04, %rem_amt
648   tail call void @use.i32(i32 %rem)
649   %inc = add nuw i32 %i.04, 1
650   %exitcond.not = icmp eq i32 %inc, %N
651   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
654 define void @simple_urem_fail_missing_nuw(i32 %N, i32 %rem_amt) nounwind {
655 ; CHECK-LABEL: simple_urem_fail_missing_nuw:
656 ; CHECK:       # %bb.0: # %entry
657 ; CHECK-NEXT:    testl %edi, %edi
658 ; CHECK-NEXT:    je .LBB10_4
659 ; CHECK-NEXT:  # %bb.1: # %for.body.preheader
660 ; CHECK-NEXT:    pushq %rbp
661 ; CHECK-NEXT:    pushq %r14
662 ; CHECK-NEXT:    pushq %rbx
663 ; CHECK-NEXT:    movl %esi, %ebx
664 ; CHECK-NEXT:    movl %edi, %ebp
665 ; CHECK-NEXT:    xorl %r14d, %r14d
666 ; CHECK-NEXT:    .p2align 4
667 ; CHECK-NEXT:  .LBB10_2: # %for.body
668 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
669 ; CHECK-NEXT:    movl %r14d, %eax
670 ; CHECK-NEXT:    xorl %edx, %edx
671 ; CHECK-NEXT:    divl %ebx
672 ; CHECK-NEXT:    movl %edx, %edi
673 ; CHECK-NEXT:    callq use.i32@PLT
674 ; CHECK-NEXT:    incl %r14d
675 ; CHECK-NEXT:    cmpl %r14d, %ebp
676 ; CHECK-NEXT:    jne .LBB10_2
677 ; CHECK-NEXT:  # %bb.3:
678 ; CHECK-NEXT:    popq %rbx
679 ; CHECK-NEXT:    popq %r14
680 ; CHECK-NEXT:    popq %rbp
681 ; CHECK-NEXT:  .LBB10_4: # %for.cond.cleanup
682 ; CHECK-NEXT:    retq
683 entry:
684   %cmp3.not = icmp eq i32 %N, 0
685   br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
687 for.cond.cleanup:
688   ret void
690 for.body:
691   %i.04 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
692   %rem = urem i32 %i.04, %rem_amt
693   tail call void @use.i32(i32 %rem)
694   %inc = add nsw i32 %i.04, 1
695   %exitcond.not = icmp eq i32 %inc, %N
696   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
699 define void @simple_urem_fail_bad_incr2(i32 %N, i32 %rem_amt) nounwind {
700 ; CHECK-LABEL: simple_urem_fail_bad_incr2:
701 ; CHECK:       # %bb.0: # %entry
702 ; CHECK-NEXT:    testl %edi, %edi
703 ; CHECK-NEXT:    je .LBB11_4
704 ; CHECK-NEXT:  # %bb.1: # %for.body.preheader
705 ; CHECK-NEXT:    pushq %rbp
706 ; CHECK-NEXT:    pushq %r14
707 ; CHECK-NEXT:    pushq %rbx
708 ; CHECK-NEXT:    movl %esi, %ebx
709 ; CHECK-NEXT:    movl %edi, %ebp
710 ; CHECK-NEXT:    xorl %r14d, %r14d
711 ; CHECK-NEXT:    .p2align 4
712 ; CHECK-NEXT:  .LBB11_2: # %for.body
713 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
714 ; CHECK-NEXT:    movl %r14d, %eax
715 ; CHECK-NEXT:    xorl %edx, %edx
716 ; CHECK-NEXT:    divl %ebx
717 ; CHECK-NEXT:    movl %edx, %edi
718 ; CHECK-NEXT:    callq use.i32@PLT
719 ; CHECK-NEXT:    addl $2, %r14d
720 ; CHECK-NEXT:    cmpl %r14d, %ebp
721 ; CHECK-NEXT:    jne .LBB11_2
722 ; CHECK-NEXT:  # %bb.3:
723 ; CHECK-NEXT:    popq %rbx
724 ; CHECK-NEXT:    popq %r14
725 ; CHECK-NEXT:    popq %rbp
726 ; CHECK-NEXT:  .LBB11_4: # %for.cond.cleanup
727 ; CHECK-NEXT:    retq
728 entry:
729   %cmp3.not = icmp eq i32 %N, 0
730   br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
732 for.cond.cleanup:
733   ret void
735 for.body:
736   %i.04 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
737   %rem = urem i32 %i.04, %rem_amt
738   tail call void @use.i32(i32 %rem)
739   %inc = add nuw i32 %i.04, 2
740   %exitcond.not = icmp eq i32 %inc, %N
741   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
744 define void @simple_urem_non_zero_entry4(i32 %N, i32 %rem_amt) nounwind {
745 ; CHECK-LABEL: simple_urem_non_zero_entry4:
746 ; CHECK:       # %bb.0: # %entry
747 ; CHECK-NEXT:    testl %edi, %edi
748 ; CHECK-NEXT:    je .LBB12_4
749 ; CHECK-NEXT:  # %bb.1: # %for.body.preheader
750 ; CHECK-NEXT:    pushq %rbp
751 ; CHECK-NEXT:    pushq %r14
752 ; CHECK-NEXT:    pushq %rbx
753 ; CHECK-NEXT:    movl %esi, %ebx
754 ; CHECK-NEXT:    movl %edi, %ebp
755 ; CHECK-NEXT:    movl $4, %r14d
756 ; CHECK-NEXT:    .p2align 4
757 ; CHECK-NEXT:  .LBB12_2: # %for.body
758 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
759 ; CHECK-NEXT:    movl %r14d, %eax
760 ; CHECK-NEXT:    xorl %edx, %edx
761 ; CHECK-NEXT:    divl %ebx
762 ; CHECK-NEXT:    movl %edx, %edi
763 ; CHECK-NEXT:    callq use.i32@PLT
764 ; CHECK-NEXT:    incl %r14d
765 ; CHECK-NEXT:    cmpl %r14d, %ebp
766 ; CHECK-NEXT:    jne .LBB12_2
767 ; CHECK-NEXT:  # %bb.3:
768 ; CHECK-NEXT:    popq %rbx
769 ; CHECK-NEXT:    popq %r14
770 ; CHECK-NEXT:    popq %rbp
771 ; CHECK-NEXT:  .LBB12_4: # %for.cond.cleanup
772 ; CHECK-NEXT:    retq
773 entry:
774   %cmp3.not = icmp eq i32 %N, 0
775   br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
777 for.cond.cleanup:
778   ret void
780 for.body:
781   %i.04 = phi i32 [ %inc, %for.body ], [ 4, %entry ]
782   %rem = urem i32 %i.04, %rem_amt
783   tail call void @use.i32(i32 %rem)
784   %inc = add nuw i32 %i.04, 1
785   %exitcond.not = icmp eq i32 %inc, %N
786   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
789 define void @simple_urem_skip_const_rem_amt(i32 %N) nounwind {
790 ; CHECK-LABEL: simple_urem_skip_const_rem_amt:
791 ; CHECK:       # %bb.0: # %entry
792 ; CHECK-NEXT:    testl %edi, %edi
793 ; CHECK-NEXT:    je .LBB13_4
794 ; CHECK-NEXT:  # %bb.1: # %for.body.preheader
795 ; CHECK-NEXT:    pushq %rbp
796 ; CHECK-NEXT:    pushq %r14
797 ; CHECK-NEXT:    pushq %rbx
798 ; CHECK-NEXT:    movl %edi, %ebx
799 ; CHECK-NEXT:    addl $-4, %ebx
800 ; CHECK-NEXT:    movl $4, %ebp
801 ; CHECK-NEXT:    movl $2938661835, %r14d # imm = 0xAF286BCB
802 ; CHECK-NEXT:    .p2align 4
803 ; CHECK-NEXT:  .LBB13_2: # %for.body
804 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
805 ; CHECK-NEXT:    movl %ebp, %eax
806 ; CHECK-NEXT:    imulq %r14, %rax
807 ; CHECK-NEXT:    shrq $32, %rax
808 ; CHECK-NEXT:    movl %ebp, %ecx
809 ; CHECK-NEXT:    subl %eax, %ecx
810 ; CHECK-NEXT:    shrl %ecx
811 ; CHECK-NEXT:    addl %eax, %ecx
812 ; CHECK-NEXT:    shrl $4, %ecx
813 ; CHECK-NEXT:    leal (%rcx,%rcx,8), %eax
814 ; CHECK-NEXT:    leal (%rcx,%rax,2), %eax
815 ; CHECK-NEXT:    movl %ebp, %edi
816 ; CHECK-NEXT:    subl %eax, %edi
817 ; CHECK-NEXT:    callq use.i32@PLT
818 ; CHECK-NEXT:    incl %ebp
819 ; CHECK-NEXT:    decl %ebx
820 ; CHECK-NEXT:    jne .LBB13_2
821 ; CHECK-NEXT:  # %bb.3:
822 ; CHECK-NEXT:    popq %rbx
823 ; CHECK-NEXT:    popq %r14
824 ; CHECK-NEXT:    popq %rbp
825 ; CHECK-NEXT:  .LBB13_4: # %for.cond.cleanup
826 ; CHECK-NEXT:    retq
827 entry:
828   %cmp3.not = icmp eq i32 %N, 0
829   br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
831 for.cond.cleanup:
832   ret void
834 for.body:
835   %i.04 = phi i32 [ %inc, %for.body ], [ 4, %entry ]
836   %rem = urem i32 %i.04, 19
837   tail call void @use.i32(i32 %rem)
838   %inc = add nuw i32 %i.04, 1
839   %exitcond.not = icmp eq i32 %inc, %N
840   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
843 define void @simple_urem_fail_no_preheader_non_canonical(i32 %N, i32 %rem_amt) nounwind {
844 ; CHECK-LABEL: simple_urem_fail_no_preheader_non_canonical:
845 ; CHECK:       # %bb.0: # %entry
846 ; CHECK-NEXT:    pushq %rbp
847 ; CHECK-NEXT:    pushq %r14
848 ; CHECK-NEXT:    pushq %rbx
849 ; CHECK-NEXT:    movl %esi, %ebx
850 ; CHECK-NEXT:    movl %edi, %ebp
851 ; CHECK-NEXT:    testl %edi, %edi
852 ; CHECK-NEXT:    je .LBB14_1
853 ; CHECK-NEXT:  # %bb.2: # %for.body1
854 ; CHECK-NEXT:    movl $1, %r14d
855 ; CHECK-NEXT:    jmp .LBB14_3
856 ; CHECK-NEXT:  .LBB14_1:
857 ; CHECK-NEXT:    xorl %r14d, %r14d
858 ; CHECK-NEXT:    .p2align 4
859 ; CHECK-NEXT:  .LBB14_3: # %for.body
860 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
861 ; CHECK-NEXT:    movl %r14d, %eax
862 ; CHECK-NEXT:    xorl %edx, %edx
863 ; CHECK-NEXT:    divl %ebx
864 ; CHECK-NEXT:    movl %edx, %edi
865 ; CHECK-NEXT:    callq use.i32@PLT
866 ; CHECK-NEXT:    incl %r14d
867 ; CHECK-NEXT:    cmpl %r14d, %ebp
868 ; CHECK-NEXT:    jne .LBB14_3
869 ; CHECK-NEXT:  # %bb.4: # %for.cond.cleanup
870 ; CHECK-NEXT:    popq %rbx
871 ; CHECK-NEXT:    popq %r14
872 ; CHECK-NEXT:    popq %rbp
873 ; CHECK-NEXT:    retq
874 entry:
875   %cmp3.not = icmp eq i32 %N, 0
876   br i1 %cmp3.not, label %for.body0, label %for.body1
878 for.cond.cleanup:
879   ret void
881 for.body0:
882   br label %for.body
884 for.body1:
885   br label %for.body
887 for.body:
888   %i.04 = phi i32 [ %inc, %for.body ], [ 0, %for.body0 ], [ 1, %for.body1 ]
889   %rem = urem i32 %i.04, %rem_amt
890   tail call void @use.i32(i32 %rem)
891   %inc = add nuw i32 %i.04, 1
892   %exitcond.not = icmp eq i32 %inc, %N
893   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
896 define void @simple_urem_multi_latch_non_canonical(i32 %N, i32 %rem_amt) nounwind {
897 ; CHECK-LABEL: simple_urem_multi_latch_non_canonical:
898 ; CHECK:       # %bb.0: # %entry
899 ; CHECK-NEXT:    testl %edi, %edi
900 ; CHECK-NEXT:    je .LBB15_6
901 ; CHECK-NEXT:  # %bb.1: # %for.body.preheader
902 ; CHECK-NEXT:    pushq %rbp
903 ; CHECK-NEXT:    pushq %r15
904 ; CHECK-NEXT:    pushq %r14
905 ; CHECK-NEXT:    pushq %r13
906 ; CHECK-NEXT:    pushq %r12
907 ; CHECK-NEXT:    pushq %rbx
908 ; CHECK-NEXT:    pushq %rax
909 ; CHECK-NEXT:    movl %esi, %ebx
910 ; CHECK-NEXT:    movl %edi, %ebp
911 ; CHECK-NEXT:    decl %ebp
912 ; CHECK-NEXT:    xorl %r12d, %r12d
913 ; CHECK-NEXT:    xorl %r14d, %r14d
914 ; CHECK-NEXT:    xorl %r13d, %r13d
915 ; CHECK-NEXT:    jmp .LBB15_2
916 ; CHECK-NEXT:    .p2align 4
917 ; CHECK-NEXT:  .LBB15_3: # %for.body.backedge
918 ; CHECK-NEXT:    # in Loop: Header=BB15_2 Depth=1
919 ; CHECK-NEXT:    incl %r14d
920 ; CHECK-NEXT:    cmpl %ebx, %r14d
921 ; CHECK-NEXT:    cmovel %r12d, %r14d
922 ; CHECK-NEXT:    incl %r13d
923 ; CHECK-NEXT:  .LBB15_2: # %for.body
924 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
925 ; CHECK-NEXT:    movl %r14d, %edi
926 ; CHECK-NEXT:    callq use.i32@PLT
927 ; CHECK-NEXT:    callq get.i1@PLT
928 ; CHECK-NEXT:    movl %eax, %r15d
929 ; CHECK-NEXT:    callq do_stuff0@PLT
930 ; CHECK-NEXT:    testb $1, %r15b
931 ; CHECK-NEXT:    je .LBB15_3
932 ; CHECK-NEXT:  # %bb.4: # %for.body0
933 ; CHECK-NEXT:    # in Loop: Header=BB15_2 Depth=1
934 ; CHECK-NEXT:    callq do_stuff1@PLT
935 ; CHECK-NEXT:    cmpl %r13d, %ebp
936 ; CHECK-NEXT:    jne .LBB15_3
937 ; CHECK-NEXT:  # %bb.5:
938 ; CHECK-NEXT:    addq $8, %rsp
939 ; CHECK-NEXT:    popq %rbx
940 ; CHECK-NEXT:    popq %r12
941 ; CHECK-NEXT:    popq %r13
942 ; CHECK-NEXT:    popq %r14
943 ; CHECK-NEXT:    popq %r15
944 ; CHECK-NEXT:    popq %rbp
945 ; CHECK-NEXT:  .LBB15_6: # %for.cond.cleanup
946 ; CHECK-NEXT:    retq
947 entry:
948   %cmp3.not = icmp eq i32 %N, 0
949   br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
951 for.cond.cleanup:
952   ret void
954 for.body:
955   %i.04 = phi i32 [ %inc, %for.body ], [ %inc, %for.body0 ], [ 0, %entry ]
956   %rem = urem i32 %i.04, %rem_amt
957   tail call void @use.i32(i32 %rem)
958   %inc = add nuw i32 %i.04, 1
959   %cond = call i1 @get.i1()
960   call void @do_stuff0()
961   br i1 %cond, label %for.body0, label %for.body
962 for.body0:
963   call void @do_stuff1()
964   %exitcond.not = icmp eq i32 %inc, %N
965   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
968 define void @simple_urem_fail_bad_loop(i32 %N, i32 %rem_amt) nounwind {
969 ; CHECK-LABEL: simple_urem_fail_bad_loop:
970 ; CHECK:       # %bb.0: # %entry
971 ; CHECK-NEXT:    pushq %rbp
972 ; CHECK-NEXT:    pushq %r14
973 ; CHECK-NEXT:    pushq %rbx
974 ; CHECK-NEXT:    movl %esi, %ebx
975 ; CHECK-NEXT:    movl %edi, %ebp
976 ; CHECK-NEXT:    callq get.i32@PLT
977 ; CHECK-NEXT:    testl %eax, %eax
978 ; CHECK-NEXT:    # implicit-def: $r14d
979 ; CHECK-NEXT:    jne .LBB16_4
980 ; CHECK-NEXT:  # %bb.1:
981 ; CHECK-NEXT:    xorl %r14d, %r14d
982 ; CHECK-NEXT:  .LBB16_2: # %for.cond
983 ; CHECK-NEXT:    cmpl %ebp, %r14d
984 ; CHECK-NEXT:    jae .LBB16_5
985 ; CHECK-NEXT:  # %bb.3: # %for.body
986 ; CHECK-NEXT:    movl %r14d, %edi
987 ; CHECK-NEXT:    xorl $1, %edi
988 ; CHECK-NEXT:    callq use.i32@PLT
989 ; CHECK-NEXT:  .LBB16_4: # %halfway
990 ; CHECK-NEXT:    movl %r14d, %eax
991 ; CHECK-NEXT:    xorl %edx, %edx
992 ; CHECK-NEXT:    divl %ebx
993 ; CHECK-NEXT:    movl %edx, %edi
994 ; CHECK-NEXT:    callq use.i32@PLT
995 ; CHECK-NEXT:    incl %r14d
996 ; CHECK-NEXT:    jmp .LBB16_2
997 ; CHECK-NEXT:  .LBB16_5: # %for.end
998 ; CHECK-NEXT:    popq %rbx
999 ; CHECK-NEXT:    popq %r14
1000 ; CHECK-NEXT:    popq %rbp
1001 ; CHECK-NEXT:    retq
1002 entry:
1003   %call = call i32 @get.i32()
1004   %tobool.not = icmp eq i32 %call, 0
1005   br i1 %tobool.not, label %for.cond, label %halfway
1007 for.cond:
1008   %i.0 = phi i32 [ %inc, %halfway ], [ 0, %entry ]
1009   %cmp = icmp ult i32 %i.0, %N
1010   br i1 %cmp, label %for.body, label %for.end
1012 for.body:
1013   %xor = xor i32 %i.0, 1
1014   call void @use.i32(i32 %xor)
1015   br label %halfway
1017 halfway:
1018   %i.1 = phi i32 [ poison, %entry ], [ %i.0, %for.body ]
1019   %rem = urem i32 %i.1, %rem_amt
1020   call void @use.i32(i32 %rem)
1021   %inc = add nuw i32 %i.1, 1
1022   br label %for.cond
1024 for.end:
1025   ret void
1028 define void @simple_urem_fail_intermediate_inc(i32 %N, i32 %rem_amt) nounwind {
1029 ; CHECK-LABEL: simple_urem_fail_intermediate_inc:
1030 ; CHECK:       # %bb.0: # %entry
1031 ; CHECK-NEXT:    testl %edi, %edi
1032 ; CHECK-NEXT:    je .LBB17_4
1033 ; CHECK-NEXT:  # %bb.1: # %for.body.preheader
1034 ; CHECK-NEXT:    pushq %r15
1035 ; CHECK-NEXT:    pushq %r14
1036 ; CHECK-NEXT:    pushq %rbx
1037 ; CHECK-NEXT:    movl %esi, %ebx
1038 ; CHECK-NEXT:    movl %edi, %r14d
1039 ; CHECK-NEXT:    negl %r14d
1040 ; CHECK-NEXT:    movl $1, %r15d
1041 ; CHECK-NEXT:    .p2align 4
1042 ; CHECK-NEXT:  .LBB17_2: # %for.body
1043 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
1044 ; CHECK-NEXT:    movl %r15d, %eax
1045 ; CHECK-NEXT:    xorl %edx, %edx
1046 ; CHECK-NEXT:    divl %ebx
1047 ; CHECK-NEXT:    movl %edx, %edi
1048 ; CHECK-NEXT:    callq use.i32@PLT
1049 ; CHECK-NEXT:    leal 1(%r14,%r15), %eax
1050 ; CHECK-NEXT:    movl %r15d, %ecx
1051 ; CHECK-NEXT:    incl %ecx
1052 ; CHECK-NEXT:    cmpl $1, %eax
1053 ; CHECK-NEXT:    movl %ecx, %r15d
1054 ; CHECK-NEXT:    jne .LBB17_2
1055 ; CHECK-NEXT:  # %bb.3:
1056 ; CHECK-NEXT:    popq %rbx
1057 ; CHECK-NEXT:    popq %r14
1058 ; CHECK-NEXT:    popq %r15
1059 ; CHECK-NEXT:  .LBB17_4: # %for.cond.cleanup
1060 ; CHECK-NEXT:    retq
1061 entry:
1062   %cmp3.not = icmp eq i32 %N, 0
1063   br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
1065 for.cond.cleanup:
1066   ret void
1068 for.body:
1069   %i.04 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
1070   %inc2 = add nuw i32 %i.04, 1
1071   %rem = urem i32 %inc2, %rem_amt
1072   tail call void @use.i32(i32 %rem)
1073   %inc = add nuw i32 %i.04, 1
1074   %exitcond.not = icmp eq i32 %inc, %N
1075   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
1078 define void @weird_loop(i64 %sub.ptr.div.i56) personality ptr null {
1079 ; CHECK-LABEL: weird_loop:
1080 ; CHECK:       # %bb.0: # %entry
1081 ; CHECK-NEXT:    .p2align 4
1082 ; CHECK-NEXT:  .LBB18_1: # %for.body
1083 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
1084 ; CHECK-NEXT:    jmp .LBB18_1
1085 entry:
1086   br label %for.preheader
1088 for.preheader:
1089   %i57.0540.us = phi i64 [ 0, %entry ], [ %add74.us, %for.body ]
1090   %add74.us = add nuw i64 %i57.0540.us, 1
1091   br label %for.body
1093 for.body:
1094   %rem.us = urem i64 %i57.0540.us, %sub.ptr.div.i56
1095   br i1 false, label %for.preheader, label %for.body
1098 define void @simple_urem_to_sel_non_zero_start_fail(i32 %N, i32 %rem_amt) nounwind {
1099 ; CHECK-LABEL: simple_urem_to_sel_non_zero_start_fail:
1100 ; CHECK:       # %bb.0: # %entry
1101 ; CHECK-NEXT:    cmpl $3, %edi
1102 ; CHECK-NEXT:    jb .LBB19_4
1103 ; CHECK-NEXT:  # %bb.1: # %for.body.preheader
1104 ; CHECK-NEXT:    pushq %rbp
1105 ; CHECK-NEXT:    pushq %r14
1106 ; CHECK-NEXT:    pushq %rbx
1107 ; CHECK-NEXT:    movl %esi, %ebx
1108 ; CHECK-NEXT:    movl %edi, %ebp
1109 ; CHECK-NEXT:    movl $2, %r14d
1110 ; CHECK-NEXT:    .p2align 4
1111 ; CHECK-NEXT:  .LBB19_2: # %for.body
1112 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
1113 ; CHECK-NEXT:    movl %r14d, %eax
1114 ; CHECK-NEXT:    xorl %edx, %edx
1115 ; CHECK-NEXT:    divl %ebx
1116 ; CHECK-NEXT:    movl %edx, %edi
1117 ; CHECK-NEXT:    callq use.i32@PLT
1118 ; CHECK-NEXT:    incl %r14d
1119 ; CHECK-NEXT:    cmpl %r14d, %ebp
1120 ; CHECK-NEXT:    jne .LBB19_2
1121 ; CHECK-NEXT:  # %bb.3:
1122 ; CHECK-NEXT:    popq %rbx
1123 ; CHECK-NEXT:    popq %r14
1124 ; CHECK-NEXT:    popq %rbp
1125 ; CHECK-NEXT:  .LBB19_4: # %for.cond.cleanup
1126 ; CHECK-NEXT:    retq
1127 entry:
1128   %cmp3.not = icmp ult i32 %N, 3
1129   br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
1131 for.cond.cleanup:
1132   ret void
1134 for.body:
1135   %i.04 = phi i32 [ %inc, %for.body ], [ 2, %entry ]
1136   %rem = urem i32 %i.04, %rem_amt
1137   tail call void @use.i32(i32 %rem)
1138   %inc = add nuw i32 %i.04, 1
1139   %exitcond.not = icmp eq i32 %inc, %N
1140   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
1143 define void @simple_urem_to_sel_non_zero_start_okay(i32 %N, i32 %rem_amt_in) nounwind {
1144 ; CHECK-LABEL: simple_urem_to_sel_non_zero_start_okay:
1145 ; CHECK:       # %bb.0: # %entry
1146 ; CHECK-NEXT:    cmpl $3, %edi
1147 ; CHECK-NEXT:    jb .LBB20_4
1148 ; CHECK-NEXT:  # %bb.1: # %for.body.preheader
1149 ; CHECK-NEXT:    pushq %rbp
1150 ; CHECK-NEXT:    pushq %r15
1151 ; CHECK-NEXT:    pushq %r14
1152 ; CHECK-NEXT:    pushq %r12
1153 ; CHECK-NEXT:    pushq %rbx
1154 ; CHECK-NEXT:    movl %esi, %ebx
1155 ; CHECK-NEXT:    movl %edi, %ebp
1156 ; CHECK-NEXT:    orl $16, %ebx
1157 ; CHECK-NEXT:    movl $2, %r14d
1158 ; CHECK-NEXT:    xorl %r15d, %r15d
1159 ; CHECK-NEXT:    movl $2, %r12d
1160 ; CHECK-NEXT:    .p2align 4
1161 ; CHECK-NEXT:  .LBB20_2: # %for.body
1162 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
1163 ; CHECK-NEXT:    movl %r14d, %edi
1164 ; CHECK-NEXT:    callq use.i32@PLT
1165 ; CHECK-NEXT:    incl %r14d
1166 ; CHECK-NEXT:    cmpl %ebx, %r14d
1167 ; CHECK-NEXT:    cmovel %r15d, %r14d
1168 ; CHECK-NEXT:    incl %r12d
1169 ; CHECK-NEXT:    cmpl %r12d, %ebp
1170 ; CHECK-NEXT:    jne .LBB20_2
1171 ; CHECK-NEXT:  # %bb.3:
1172 ; CHECK-NEXT:    popq %rbx
1173 ; CHECK-NEXT:    popq %r12
1174 ; CHECK-NEXT:    popq %r14
1175 ; CHECK-NEXT:    popq %r15
1176 ; CHECK-NEXT:    popq %rbp
1177 ; CHECK-NEXT:  .LBB20_4: # %for.cond.cleanup
1178 ; CHECK-NEXT:    retq
1179 entry:
1180   %rem_amt = or i32 %rem_amt_in, 16
1181   %cmp3.not = icmp ult i32 %N, 3
1182   br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
1184 for.cond.cleanup:
1185   ret void
1187 for.body:
1188   %i.04 = phi i32 [ %inc, %for.body ], [ 2, %entry ]
1189   %rem = urem i32 %i.04, %rem_amt
1190   tail call void @use.i32(i32 %rem)
1191   %inc = add nuw i32 %i.04, 1
1192   %exitcond.not = icmp eq i32 %inc, %N
1193   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
1196 define void @simple_urem_to_sel_non_zero_start_through_add(i32 %N, i32 %rem_amt_in) nounwind {
1197 ; CHECK-LABEL: simple_urem_to_sel_non_zero_start_through_add:
1198 ; CHECK:       # %bb.0: # %entry
1199 ; CHECK-NEXT:    cmpl $3, %edi
1200 ; CHECK-NEXT:    jb .LBB21_4
1201 ; CHECK-NEXT:  # %bb.1: # %for.body.preheader
1202 ; CHECK-NEXT:    pushq %r15
1203 ; CHECK-NEXT:    pushq %r14
1204 ; CHECK-NEXT:    pushq %rbx
1205 ; CHECK-NEXT:    movl %esi, %ebx
1206 ; CHECK-NEXT:    movl %edi, %r14d
1207 ; CHECK-NEXT:    orl $16, %ebx
1208 ; CHECK-NEXT:    negl %r14d
1209 ; CHECK-NEXT:    movl $7, %r15d
1210 ; CHECK-NEXT:    .p2align 4
1211 ; CHECK-NEXT:  .LBB21_2: # %for.body
1212 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
1213 ; CHECK-NEXT:    movl %r15d, %eax
1214 ; CHECK-NEXT:    xorl %edx, %edx
1215 ; CHECK-NEXT:    divl %ebx
1216 ; CHECK-NEXT:    movl %edx, %edi
1217 ; CHECK-NEXT:    callq use.i32@PLT
1218 ; CHECK-NEXT:    leal 1(%r14,%r15), %eax
1219 ; CHECK-NEXT:    movl %r15d, %ecx
1220 ; CHECK-NEXT:    incl %ecx
1221 ; CHECK-NEXT:    cmpl $5, %eax
1222 ; CHECK-NEXT:    movl %ecx, %r15d
1223 ; CHECK-NEXT:    jne .LBB21_2
1224 ; CHECK-NEXT:  # %bb.3:
1225 ; CHECK-NEXT:    popq %rbx
1226 ; CHECK-NEXT:    popq %r14
1227 ; CHECK-NEXT:    popq %r15
1228 ; CHECK-NEXT:  .LBB21_4: # %for.cond.cleanup
1229 ; CHECK-NEXT:    retq
1230 entry:
1231   %rem_amt = or i32 %rem_amt_in, 16
1232   %cmp3.not = icmp ult i32 %N, 3
1233   br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
1235 for.cond.cleanup:
1236   ret void
1238 for.body:
1239   %i.04 = phi i32 [ %inc, %for.body ], [ 2, %entry ]
1240   %i_with_off = add nuw i32 %i.04, 5
1241   %rem = urem i32 %i_with_off, %rem_amt
1242   tail call void @use.i32(i32 %rem)
1243   %inc = add nuw i32 %i.04, 1
1244   %exitcond.not = icmp eq i32 %inc, %N
1245   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
1248 define void @simple_urem_to_sel_non_zero_start_through_add_fail_missing_nuw(i32 %N, i32 %rem_amt_in) nounwind {
1249 ; CHECK-LABEL: simple_urem_to_sel_non_zero_start_through_add_fail_missing_nuw:
1250 ; CHECK:       # %bb.0: # %entry
1251 ; CHECK-NEXT:    cmpl $3, %edi
1252 ; CHECK-NEXT:    jb .LBB22_4
1253 ; CHECK-NEXT:  # %bb.1: # %for.body.preheader
1254 ; CHECK-NEXT:    pushq %r15
1255 ; CHECK-NEXT:    pushq %r14
1256 ; CHECK-NEXT:    pushq %rbx
1257 ; CHECK-NEXT:    movl %esi, %ebx
1258 ; CHECK-NEXT:    movl %edi, %r14d
1259 ; CHECK-NEXT:    orl $16, %ebx
1260 ; CHECK-NEXT:    negl %r14d
1261 ; CHECK-NEXT:    movl $7, %r15d
1262 ; CHECK-NEXT:    .p2align 4
1263 ; CHECK-NEXT:  .LBB22_2: # %for.body
1264 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
1265 ; CHECK-NEXT:    movl %r15d, %eax
1266 ; CHECK-NEXT:    xorl %edx, %edx
1267 ; CHECK-NEXT:    divl %ebx
1268 ; CHECK-NEXT:    movl %edx, %edi
1269 ; CHECK-NEXT:    callq use.i32@PLT
1270 ; CHECK-NEXT:    leal 1(%r14,%r15), %eax
1271 ; CHECK-NEXT:    movl %r15d, %ecx
1272 ; CHECK-NEXT:    incl %ecx
1273 ; CHECK-NEXT:    cmpl $5, %eax
1274 ; CHECK-NEXT:    movl %ecx, %r15d
1275 ; CHECK-NEXT:    jne .LBB22_2
1276 ; CHECK-NEXT:  # %bb.3:
1277 ; CHECK-NEXT:    popq %rbx
1278 ; CHECK-NEXT:    popq %r14
1279 ; CHECK-NEXT:    popq %r15
1280 ; CHECK-NEXT:  .LBB22_4: # %for.cond.cleanup
1281 ; CHECK-NEXT:    retq
1282 entry:
1283   %rem_amt = or i32 %rem_amt_in, 16
1284   %cmp3.not = icmp ult i32 %N, 3
1285   br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
1287 for.cond.cleanup:
1288   ret void
1290 for.body:
1291   %i.04 = phi i32 [ %inc, %for.body ], [ 2, %entry ]
1292   %i_with_off = add i32 %i.04, 5
1293   %rem = urem i32 %i_with_off, %rem_amt
1294   tail call void @use.i32(i32 %rem)
1295   %inc = add nuw i32 %i.04, 1
1296   %exitcond.not = icmp eq i32 %inc, %N
1297   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
1300 define void @simple_urem_to_sel_non_zero_start_through_add_fail_no_simplify_rem(i32 %N, i32 %rem_amt) nounwind {
1301 ; CHECK-LABEL: simple_urem_to_sel_non_zero_start_through_add_fail_no_simplify_rem:
1302 ; CHECK:       # %bb.0: # %entry
1303 ; CHECK-NEXT:    cmpl $3, %edi
1304 ; CHECK-NEXT:    jb .LBB23_4
1305 ; CHECK-NEXT:  # %bb.1: # %for.body.preheader
1306 ; CHECK-NEXT:    pushq %r15
1307 ; CHECK-NEXT:    pushq %r14
1308 ; CHECK-NEXT:    pushq %rbx
1309 ; CHECK-NEXT:    movl %esi, %ebx
1310 ; CHECK-NEXT:    movl %edi, %r14d
1311 ; CHECK-NEXT:    negl %r14d
1312 ; CHECK-NEXT:    movl $7, %r15d
1313 ; CHECK-NEXT:    .p2align 4
1314 ; CHECK-NEXT:  .LBB23_2: # %for.body
1315 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
1316 ; CHECK-NEXT:    movl %r15d, %eax
1317 ; CHECK-NEXT:    xorl %edx, %edx
1318 ; CHECK-NEXT:    divl %ebx
1319 ; CHECK-NEXT:    movl %edx, %edi
1320 ; CHECK-NEXT:    callq use.i32@PLT
1321 ; CHECK-NEXT:    leal 1(%r14,%r15), %eax
1322 ; CHECK-NEXT:    movl %r15d, %ecx
1323 ; CHECK-NEXT:    incl %ecx
1324 ; CHECK-NEXT:    cmpl $5, %eax
1325 ; CHECK-NEXT:    movl %ecx, %r15d
1326 ; CHECK-NEXT:    jne .LBB23_2
1327 ; CHECK-NEXT:  # %bb.3:
1328 ; CHECK-NEXT:    popq %rbx
1329 ; CHECK-NEXT:    popq %r14
1330 ; CHECK-NEXT:    popq %r15
1331 ; CHECK-NEXT:  .LBB23_4: # %for.cond.cleanup
1332 ; CHECK-NEXT:    retq
1333 entry:
1334   %cmp3.not = icmp ult i32 %N, 3
1335   br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
1337 for.cond.cleanup:
1338   ret void
1340 for.body:
1341   %i.04 = phi i32 [ %inc, %for.body ], [ 2, %entry ]
1342   %i_with_off = add nuw i32 %i.04, 5
1343   %rem = urem i32 %i_with_off, %rem_amt
1344   tail call void @use.i32(i32 %rem)
1345   %inc = add nuw i32 %i.04, 1
1346   %exitcond.not = icmp eq i32 %inc, %N
1347   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
1350 define void @simple_urem_to_sel_non_zero_start_through_sub(i32 %N, i32 %rem_amt, i32 %start) nounwind {
1351 ; CHECK-LABEL: simple_urem_to_sel_non_zero_start_through_sub:
1352 ; CHECK:       # %bb.0: # %entry
1353 ; CHECK-NEXT:    pushq %rbp
1354 ; CHECK-NEXT:    pushq %r15
1355 ; CHECK-NEXT:    pushq %r14
1356 ; CHECK-NEXT:    pushq %r12
1357 ; CHECK-NEXT:    pushq %rbx
1358 ; CHECK-NEXT:    movl %edi, %ebp
1359 ; CHECK-NEXT:    subl %edx, %ebp
1360 ; CHECK-NEXT:    jbe .LBB24_3
1361 ; CHECK-NEXT:  # %bb.1: # %for.body.preheader
1362 ; CHECK-NEXT:    movl %esi, %ebx
1363 ; CHECK-NEXT:    xorl %r15d, %r15d
1364 ; CHECK-NEXT:    xorl %r14d, %r14d
1365 ; CHECK-NEXT:    xorl %r12d, %r12d
1366 ; CHECK-NEXT:    .p2align 4
1367 ; CHECK-NEXT:  .LBB24_2: # %for.body
1368 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
1369 ; CHECK-NEXT:    movl %r14d, %edi
1370 ; CHECK-NEXT:    callq use.i32@PLT
1371 ; CHECK-NEXT:    incl %r14d
1372 ; CHECK-NEXT:    cmpl %ebx, %r14d
1373 ; CHECK-NEXT:    cmovel %r15d, %r14d
1374 ; CHECK-NEXT:    incl %r12d
1375 ; CHECK-NEXT:    cmpl %r12d, %ebp
1376 ; CHECK-NEXT:    jne .LBB24_2
1377 ; CHECK-NEXT:  .LBB24_3: # %for.cond.cleanup
1378 ; CHECK-NEXT:    popq %rbx
1379 ; CHECK-NEXT:    popq %r12
1380 ; CHECK-NEXT:    popq %r14
1381 ; CHECK-NEXT:    popq %r15
1382 ; CHECK-NEXT:    popq %rbp
1383 ; CHECK-NEXT:    retq
1384 entry:
1385   %cmp3.not = icmp ule i32 %N, %start
1386   br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
1388 for.cond.cleanup:
1389   ret void
1391 for.body:
1392   %i.04 = phi i32 [ %inc, %for.body ], [ %start, %entry ]
1393   %i_with_off = sub nuw i32 %i.04, %start
1394   %rem = urem i32 %i_with_off, %rem_amt
1395   tail call void @use.i32(i32 %rem)
1396   %inc = add nuw i32 %i.04, 1
1397   %exitcond.not = icmp eq i32 %inc, %N
1398   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
1401 define void @simple_urem_to_sel_non_zero_start_through_sub_no_simplfy(i32 %N, i32 %rem_amt, i32 %start) nounwind {
1402 ; CHECK-LABEL: simple_urem_to_sel_non_zero_start_through_sub_no_simplfy:
1403 ; CHECK:       # %bb.0: # %entry
1404 ; CHECK-NEXT:    cmpl %edx, %edi
1405 ; CHECK-NEXT:    jbe .LBB25_4
1406 ; CHECK-NEXT:  # %bb.1: # %for.body.preheader
1407 ; CHECK-NEXT:    pushq %r15
1408 ; CHECK-NEXT:    pushq %r14
1409 ; CHECK-NEXT:    pushq %rbx
1410 ; CHECK-NEXT:    movl %edx, %r15d
1411 ; CHECK-NEXT:    movl %esi, %ebx
1412 ; CHECK-NEXT:    movl %edi, %r14d
1413 ; CHECK-NEXT:    negl %r14d
1414 ; CHECK-NEXT:    addl $-2, %r15d
1415 ; CHECK-NEXT:    .p2align 4
1416 ; CHECK-NEXT:  .LBB25_2: # %for.body
1417 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
1418 ; CHECK-NEXT:    movl %r15d, %eax
1419 ; CHECK-NEXT:    xorl %edx, %edx
1420 ; CHECK-NEXT:    divl %ebx
1421 ; CHECK-NEXT:    movl %edx, %edi
1422 ; CHECK-NEXT:    callq use.i32@PLT
1423 ; CHECK-NEXT:    leal 1(%r14,%r15), %eax
1424 ; CHECK-NEXT:    movl %r15d, %ecx
1425 ; CHECK-NEXT:    incl %ecx
1426 ; CHECK-NEXT:    cmpl $-2, %eax
1427 ; CHECK-NEXT:    movl %ecx, %r15d
1428 ; CHECK-NEXT:    jne .LBB25_2
1429 ; CHECK-NEXT:  # %bb.3:
1430 ; CHECK-NEXT:    popq %rbx
1431 ; CHECK-NEXT:    popq %r14
1432 ; CHECK-NEXT:    popq %r15
1433 ; CHECK-NEXT:  .LBB25_4: # %for.cond.cleanup
1434 ; CHECK-NEXT:    retq
1435 entry:
1436   %cmp3.not = icmp ule i32 %N, %start
1437   br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
1439 for.cond.cleanup:
1440   ret void
1442 for.body:
1443   %i.04 = phi i32 [ %inc, %for.body ], [ %start, %entry ]
1444   %i_with_off = sub nuw i32 %i.04, 2
1445   %rem = urem i32 %i_with_off, %rem_amt
1446   tail call void @use.i32(i32 %rem)
1447   %inc = add nuw i32 %i.04, 1
1448   %exitcond.not = icmp eq i32 %inc, %N
1449   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body