xref: /llvm-project/llvm/test/CodeGen/X86/fold-loop-of-urem.ll (revision e6bf48d11047e970cb24554a01b65b566d6b5d22)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
3
4declare void @use.i32(i32)
5declare void @use.2xi64(<2 x i64>)
6declare void @do_stuff0()
7declare void @do_stuff1()
8declare i1 @get.i1()
9declare i32 @get.i32()
10
11define 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
46entry:
47  %cmp3.not = icmp eq i32 %N, 0
48  br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
49
50for.cond.cleanup:
51  ret void
52
53for.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
60}
61
62define 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
94entry:
95  %cmp3.not = icmp eq i32 %N, 0
96  br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
97
98for.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
103
104for.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
110}
111
112define 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
168entry:
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
172
173for.cond.cleanup:
174  ret void
175
176for.body:
177  %i.04 = phi i32 [ %inc, %for.inner.cond.cleanup ], [ 0, %entry ]
178
179  %cmp_inner = icmp eq i32 %M, 0
180  br i1 %cmp_inner, label %for.inner.cond.cleanup, label %for.inner.body
181
182for.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
189
190for.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
194}
195
196define 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
247entry:
248  %cmp3.not = icmp eq i32 %N, 0
249  br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
250
251for.cond.cleanup:
252  ret void
253
254for.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
259
260for.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
267
268for.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
272}
273
274define 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
328entry:
329  %cmp3.not = icmp eq i32 %N, 0
330  br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
331
332for.cond.cleanup:
333  ret void
334
335for.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
339for.body0:
340  %cond1 = call i1 @get.i1()
341  br i1 %cond1, label %for.body1, label %for.body2
342for.body2:
343  %cond2 = call i1 @get.i1()
344  br i1 %cond2, label %for.body1, label %for.body.tail
345for.body1:
346  %rem = urem i32 %i.04, %rem_amt
347  tail call void @use.i32(i32 %rem)
348  br label %for.body.tail
349for.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
353}
354
355define 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
409entry:
410  %cmp3.not = icmp eq i32 %N, 0
411  br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
412
413for.cond.cleanup:
414  ret void
415
416for.body:
417  %cond0 = call i1 @get.i1()
418  br i1 %cond0, label %for.body0, label %for.body2
419for.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
424for.body2:
425  %cond2 = call i1 @get.i1()
426  br i1 %cond2, label %for.body1, label %for.body.tail
427for.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
432for.body.tail:
433  %exitcond.not = call i1 @get.i1()
434  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
435}
436
437define 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
471entry:
472  br label %for.body
473
474for.cond.cleanup:
475  ret void
476
477for.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
484}
485
486define 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
526entry:
527  %cmp3.not = icmp eq i32 %N, 0
528  br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
529
530for.cond.cleanup:
531  ret void
532
533for.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
537for.body0:
538  %some_val = call i32 @get.i32()
539  br label %for.body.tail
540
541for.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
548}
549
550define 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
591entry:
592  %cmp3.not = icmp ult i32 %N, 2
593  br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
594
595for.cond.cleanup:
596  ret void
597
598for.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
607}
608
609define 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
638entry:
639  %cmp3.not = icmp eq i32 %N, 0
640  br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
641
642for.cond.cleanup:
643  ret void
644
645for.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
652}
653
654define 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
683entry:
684  %cmp3.not = icmp eq i32 %N, 0
685  br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
686
687for.cond.cleanup:
688  ret void
689
690for.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
697}
698
699define 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
728entry:
729  %cmp3.not = icmp eq i32 %N, 0
730  br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
731
732for.cond.cleanup:
733  ret void
734
735for.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
742}
743
744define 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
773entry:
774  %cmp3.not = icmp eq i32 %N, 0
775  br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
776
777for.cond.cleanup:
778  ret void
779
780for.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
787}
788
789define 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
827entry:
828  %cmp3.not = icmp eq i32 %N, 0
829  br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
830
831for.cond.cleanup:
832  ret void
833
834for.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
841}
842
843define 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
874entry:
875  %cmp3.not = icmp eq i32 %N, 0
876  br i1 %cmp3.not, label %for.body0, label %for.body1
877
878for.cond.cleanup:
879  ret void
880
881for.body0:
882  br label %for.body
883
884for.body1:
885  br label %for.body
886
887for.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
894}
895
896define 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
947entry:
948  %cmp3.not = icmp eq i32 %N, 0
949  br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
950
951for.cond.cleanup:
952  ret void
953
954for.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
962for.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
966}
967
968define 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
1002entry:
1003  %call = call i32 @get.i32()
1004  %tobool.not = icmp eq i32 %call, 0
1005  br i1 %tobool.not, label %for.cond, label %halfway
1006
1007for.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
1011
1012for.body:
1013  %xor = xor i32 %i.0, 1
1014  call void @use.i32(i32 %xor)
1015  br label %halfway
1016
1017halfway:
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
1023
1024for.end:
1025  ret void
1026}
1027
1028define 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
1061entry:
1062  %cmp3.not = icmp eq i32 %N, 0
1063  br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
1064
1065for.cond.cleanup:
1066  ret void
1067
1068for.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
1076}
1077
1078define 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
1085entry:
1086  br label %for.preheader
1087
1088for.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
1092
1093for.body:
1094  %rem.us = urem i64 %i57.0540.us, %sub.ptr.div.i56
1095  br i1 false, label %for.preheader, label %for.body
1096}
1097
1098define 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
1127entry:
1128  %cmp3.not = icmp ult i32 %N, 3
1129  br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
1130
1131for.cond.cleanup:
1132  ret void
1133
1134for.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
1141}
1142
1143define 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
1179entry:
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
1183
1184for.cond.cleanup:
1185  ret void
1186
1187for.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
1194}
1195
1196define 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
1230entry:
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
1234
1235for.cond.cleanup:
1236  ret void
1237
1238for.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
1246}
1247
1248define 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
1282entry:
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
1286
1287for.cond.cleanup:
1288  ret void
1289
1290for.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
1298}
1299
1300define 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
1333entry:
1334  %cmp3.not = icmp ult i32 %N, 3
1335  br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
1336
1337for.cond.cleanup:
1338  ret void
1339
1340for.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
1348}
1349
1350define 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
1384entry:
1385  %cmp3.not = icmp ule i32 %N, %start
1386  br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
1387
1388for.cond.cleanup:
1389  ret void
1390
1391for.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
1399}
1400
1401define 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
1435entry:
1436  %cmp3.not = icmp ule i32 %N, %start
1437  br i1 %cmp3.not, label %for.cond.cleanup, label %for.body
1438
1439for.cond.cleanup:
1440  ret void
1441
1442for.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
1450}
1451