1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-- | FileCheck %s
3
4; Don't optimize away zext-inreg and sext-inreg on the loop induction
5; variable, because it isn't safe to do so in these cases.
6
7define void @count_up(double* %d, i64 %n) nounwind {
8; CHECK-LABEL: count_up:
9; CHECK:       # %bb.0: # %entry
10; CHECK-NEXT:    movl $10, %eax
11; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
12; CHECK-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
13; CHECK-NEXT:    movsd {{.*#+}} xmm2 = mem[0],zero
14; CHECK-NEXT:    .p2align 4, 0x90
15; CHECK-NEXT:  .LBB0_1: # %loop
16; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
17; CHECK-NEXT:    movzbl %al, %ecx
18; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
19; CHECK-NEXT:    mulsd %xmm0, %xmm3
20; CHECK-NEXT:    movsd %xmm3, (%rdi,%rcx,8)
21; CHECK-NEXT:    movl %eax, %ecx
22; CHECK-NEXT:    andl $16777215, %ecx # imm = 0xFFFFFF
23; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
24; CHECK-NEXT:    mulsd %xmm1, %xmm3
25; CHECK-NEXT:    movsd %xmm3, (%rdi,%rcx,8)
26; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
27; CHECK-NEXT:    mulsd %xmm2, %xmm3
28; CHECK-NEXT:    movsd %xmm3, (%rdi,%rax,8)
29; CHECK-NEXT:    incq %rax
30; CHECK-NEXT:    jne .LBB0_1
31; CHECK-NEXT:  # %bb.2: # %return
32; CHECK-NEXT:    retq
33entry:
34	br label %loop
35
36loop:
37	%indvar = phi i64 [ 10, %entry ], [ %indvar.next, %loop ]
38	%indvar.i8 = and i64 %indvar, 255
39	%t0 = getelementptr double, double* %d, i64 %indvar.i8
40	%t1 = load double, double* %t0
41	%t2 = fmul double %t1, 0.1
42	store double %t2, double* %t0
43	%indvar.i24 = and i64 %indvar, 16777215
44	%t3 = getelementptr double, double* %d, i64 %indvar.i24
45	%t4 = load double, double* %t3
46	%t5 = fmul double %t4, 2.3
47	store double %t5, double* %t3
48	%t6 = getelementptr double, double* %d, i64 %indvar
49	%t7 = load double, double* %t6
50	%t8 = fmul double %t7, 4.5
51	store double %t8, double* %t6
52	%indvar.next = add i64 %indvar, 1
53	%exitcond = icmp eq i64 %indvar.next, 0
54	br i1 %exitcond, label %return, label %loop
55
56return:
57	ret void
58}
59
60define void @count_down(double* %d, i64 %n) nounwind {
61; CHECK-LABEL: count_down:
62; CHECK:       # %bb.0: # %entry
63; CHECK-NEXT:    movl $10, %eax
64; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
65; CHECK-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
66; CHECK-NEXT:    movsd {{.*#+}} xmm2 = mem[0],zero
67; CHECK-NEXT:    .p2align 4, 0x90
68; CHECK-NEXT:  .LBB1_1: # %loop
69; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
70; CHECK-NEXT:    movzbl %al, %ecx
71; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
72; CHECK-NEXT:    mulsd %xmm0, %xmm3
73; CHECK-NEXT:    movsd %xmm3, (%rdi,%rcx,8)
74; CHECK-NEXT:    movl %eax, %ecx
75; CHECK-NEXT:    andl $16777215, %ecx # imm = 0xFFFFFF
76; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
77; CHECK-NEXT:    mulsd %xmm1, %xmm3
78; CHECK-NEXT:    movsd %xmm3, (%rdi,%rcx,8)
79; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
80; CHECK-NEXT:    mulsd %xmm2, %xmm3
81; CHECK-NEXT:    movsd %xmm3, (%rdi,%rax,8)
82; CHECK-NEXT:    decq %rax
83; CHECK-NEXT:    cmpq $20, %rax
84; CHECK-NEXT:    jne .LBB1_1
85; CHECK-NEXT:  # %bb.2: # %return
86; CHECK-NEXT:    retq
87entry:
88	br label %loop
89
90loop:
91	%indvar = phi i64 [ 10, %entry ], [ %indvar.next, %loop ]
92	%indvar.i8 = and i64 %indvar, 255
93	%t0 = getelementptr double, double* %d, i64 %indvar.i8
94	%t1 = load double, double* %t0
95	%t2 = fmul double %t1, 0.1
96	store double %t2, double* %t0
97	%indvar.i24 = and i64 %indvar, 16777215
98	%t3 = getelementptr double, double* %d, i64 %indvar.i24
99	%t4 = load double, double* %t3
100	%t5 = fmul double %t4, 2.3
101	store double %t5, double* %t3
102	%t6 = getelementptr double, double* %d, i64 %indvar
103	%t7 = load double, double* %t6
104	%t8 = fmul double %t7, 4.5
105	store double %t8, double* %t6
106	%indvar.next = sub i64 %indvar, 1
107	%exitcond = icmp eq i64 %indvar.next, 20
108	br i1 %exitcond, label %return, label %loop
109
110return:
111	ret void
112}
113
114define void @count_up_signed(double* %d, i64 %n) nounwind {
115; CHECK-LABEL: count_up_signed:
116; CHECK:       # %bb.0: # %entry
117; CHECK-NEXT:    movl $10, %eax
118; CHECK-NEXT:    movl $167772160, %ecx # imm = 0xA000000
119; CHECK-NEXT:    movl $2560, %edx # imm = 0xA00
120; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
121; CHECK-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
122; CHECK-NEXT:    movsd {{.*#+}} xmm2 = mem[0],zero
123; CHECK-NEXT:    .p2align 4, 0x90
124; CHECK-NEXT:  .LBB2_1: # %loop
125; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
126; CHECK-NEXT:    movq %rdx, %rsi
127; CHECK-NEXT:    sarq $8, %rsi
128; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
129; CHECK-NEXT:    mulsd %xmm0, %xmm3
130; CHECK-NEXT:    movsd %xmm3, (%rdi,%rsi,8)
131; CHECK-NEXT:    movq %rcx, %rsi
132; CHECK-NEXT:    sarq $24, %rsi
133; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
134; CHECK-NEXT:    mulsd %xmm1, %xmm3
135; CHECK-NEXT:    movsd %xmm3, (%rdi,%rsi,8)
136; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
137; CHECK-NEXT:    mulsd %xmm2, %xmm3
138; CHECK-NEXT:    movsd %xmm3, (%rdi,%rax,8)
139; CHECK-NEXT:    addq $16777216, %rcx # imm = 0x1000000
140; CHECK-NEXT:    addq $256, %rdx # imm = 0x100
141; CHECK-NEXT:    incq %rax
142; CHECK-NEXT:    jne .LBB2_1
143; CHECK-NEXT:  # %bb.2: # %return
144; CHECK-NEXT:    retq
145entry:
146	br label %loop
147
148loop:
149	%indvar = phi i64 [ 10, %entry ], [ %indvar.next, %loop ]
150        %s0 = shl i64 %indvar, 8
151	%indvar.i8 = ashr i64 %s0, 8
152	%t0 = getelementptr double, double* %d, i64 %indvar.i8
153	%t1 = load double, double* %t0
154	%t2 = fmul double %t1, 0.1
155	store double %t2, double* %t0
156	%s1 = shl i64 %indvar, 24
157	%indvar.i24 = ashr i64 %s1, 24
158	%t3 = getelementptr double, double* %d, i64 %indvar.i24
159	%t4 = load double, double* %t3
160	%t5 = fmul double %t4, 2.3
161	store double %t5, double* %t3
162	%t6 = getelementptr double, double* %d, i64 %indvar
163	%t7 = load double, double* %t6
164	%t8 = fmul double %t7, 4.5
165	store double %t8, double* %t6
166	%indvar.next = add i64 %indvar, 1
167	%exitcond = icmp eq i64 %indvar.next, 0
168	br i1 %exitcond, label %return, label %loop
169
170return:
171	ret void
172}
173
174define void @count_down_signed(double* %d, i64 %n) nounwind {
175; CHECK-LABEL: count_down_signed:
176; CHECK:       # %bb.0: # %entry
177; CHECK-NEXT:    movq $-10, %rax
178; CHECK-NEXT:    movl $167772160, %ecx # imm = 0xA000000
179; CHECK-NEXT:    movl $2560, %edx # imm = 0xA00
180; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
181; CHECK-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
182; CHECK-NEXT:    movsd {{.*#+}} xmm2 = mem[0],zero
183; CHECK-NEXT:    .p2align 4, 0x90
184; CHECK-NEXT:  .LBB3_1: # %loop
185; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
186; CHECK-NEXT:    movq %rdx, %rsi
187; CHECK-NEXT:    sarq $8, %rsi
188; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
189; CHECK-NEXT:    mulsd %xmm0, %xmm3
190; CHECK-NEXT:    movsd %xmm3, (%rdi,%rsi,8)
191; CHECK-NEXT:    movq %rcx, %rsi
192; CHECK-NEXT:    sarq $24, %rsi
193; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
194; CHECK-NEXT:    mulsd %xmm1, %xmm3
195; CHECK-NEXT:    movsd %xmm3, (%rdi,%rsi,8)
196; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
197; CHECK-NEXT:    mulsd %xmm2, %xmm3
198; CHECK-NEXT:    movsd %xmm3, 160(%rdi,%rax,8)
199; CHECK-NEXT:    addq $-16777216, %rcx # imm = 0xFF000000
200; CHECK-NEXT:    addq $-256, %rdx
201; CHECK-NEXT:    decq %rax
202; CHECK-NEXT:    jne .LBB3_1
203; CHECK-NEXT:  # %bb.2: # %return
204; CHECK-NEXT:    retq
205entry:
206	br label %loop
207
208loop:
209	%indvar = phi i64 [ 10, %entry ], [ %indvar.next, %loop ]
210        %s0 = shl i64 %indvar, 8
211	%indvar.i8 = ashr i64 %s0, 8
212	%t0 = getelementptr double, double* %d, i64 %indvar.i8
213	%t1 = load double, double* %t0
214	%t2 = fmul double %t1, 0.1
215	store double %t2, double* %t0
216	%s1 = shl i64 %indvar, 24
217	%indvar.i24 = ashr i64 %s1, 24
218	%t3 = getelementptr double, double* %d, i64 %indvar.i24
219	%t4 = load double, double* %t3
220	%t5 = fmul double %t4, 2.3
221	store double %t5, double* %t3
222	%t6 = getelementptr double, double* %d, i64 %indvar
223	%t7 = load double, double* %t6
224	%t8 = fmul double %t7, 4.5
225	store double %t8, double* %t6
226	%indvar.next = sub i64 %indvar, 1
227	%exitcond = icmp eq i64 %indvar.next, 20
228	br i1 %exitcond, label %return, label %loop
229
230return:
231	ret void
232}
233
234define void @another_count_up(double* %d, i64 %n) nounwind {
235; CHECK-LABEL: another_count_up:
236; CHECK:       # %bb.0: # %entry
237; CHECK-NEXT:    xorl %eax, %eax
238; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
239; CHECK-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
240; CHECK-NEXT:    movsd {{.*#+}} xmm2 = mem[0],zero
241; CHECK-NEXT:    .p2align 4, 0x90
242; CHECK-NEXT:  .LBB4_1: # %loop
243; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
244; CHECK-NEXT:    movzbl %al, %ecx
245; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
246; CHECK-NEXT:    mulsd %xmm0, %xmm3
247; CHECK-NEXT:    movsd %xmm3, (%rdi,%rcx,8)
248; CHECK-NEXT:    movl %eax, %ecx
249; CHECK-NEXT:    andl $16777215, %ecx # imm = 0xFFFFFF
250; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
251; CHECK-NEXT:    mulsd %xmm1, %xmm3
252; CHECK-NEXT:    movsd %xmm3, (%rdi,%rcx,8)
253; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
254; CHECK-NEXT:    mulsd %xmm2, %xmm3
255; CHECK-NEXT:    movsd %xmm3, (%rdi,%rax,8)
256; CHECK-NEXT:    incq %rax
257; CHECK-NEXT:    cmpq %rax, %rsi
258; CHECK-NEXT:    jne .LBB4_1
259; CHECK-NEXT:  # %bb.2: # %return
260; CHECK-NEXT:    retq
261entry:
262        br label %loop
263
264loop:
265        %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop ]
266        %indvar.i8 = and i64 %indvar, 255
267        %t0 = getelementptr double, double* %d, i64 %indvar.i8
268        %t1 = load double, double* %t0
269        %t2 = fmul double %t1, 0.1
270        store double %t2, double* %t0
271        %indvar.i24 = and i64 %indvar, 16777215
272        %t3 = getelementptr double, double* %d, i64 %indvar.i24
273        %t4 = load double, double* %t3
274        %t5 = fmul double %t4, 2.3
275        store double %t5, double* %t3
276        %t6 = getelementptr double, double* %d, i64 %indvar
277        %t7 = load double, double* %t6
278        %t8 = fmul double %t7, 4.5
279        store double %t8, double* %t6
280        %indvar.next = add i64 %indvar, 1
281        %exitcond = icmp eq i64 %indvar.next, %n
282        br i1 %exitcond, label %return, label %loop
283
284return:
285        ret void
286}
287
288define void @another_count_down(double* %d, i64 %n) nounwind {
289; CHECK-LABEL: another_count_down:
290; CHECK:       # %bb.0: # %entry
291; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
292; CHECK-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
293; CHECK-NEXT:    movsd {{.*#+}} xmm2 = mem[0],zero
294; CHECK-NEXT:    .p2align 4, 0x90
295; CHECK-NEXT:  .LBB5_1: # %loop
296; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
297; CHECK-NEXT:    movzbl %sil, %eax
298; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
299; CHECK-NEXT:    mulsd %xmm0, %xmm3
300; CHECK-NEXT:    movsd %xmm3, (%rdi,%rax,8)
301; CHECK-NEXT:    movl %esi, %eax
302; CHECK-NEXT:    andl $16777215, %eax # imm = 0xFFFFFF
303; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
304; CHECK-NEXT:    mulsd %xmm1, %xmm3
305; CHECK-NEXT:    movsd %xmm3, (%rdi,%rax,8)
306; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
307; CHECK-NEXT:    mulsd %xmm2, %xmm3
308; CHECK-NEXT:    movsd %xmm3, (%rdi,%rsi,8)
309; CHECK-NEXT:    decq %rsi
310; CHECK-NEXT:    cmpq $10, %rsi
311; CHECK-NEXT:    jne .LBB5_1
312; CHECK-NEXT:  # %bb.2: # %return
313; CHECK-NEXT:    retq
314entry:
315        br label %loop
316
317loop:
318        %indvar = phi i64 [ %n, %entry ], [ %indvar.next, %loop ]
319        %indvar.i8 = and i64 %indvar, 255
320        %t0 = getelementptr double, double* %d, i64 %indvar.i8
321        %t1 = load double, double* %t0
322        %t2 = fmul double %t1, 0.1
323        store double %t2, double* %t0
324        %indvar.i24 = and i64 %indvar, 16777215
325        %t3 = getelementptr double, double* %d, i64 %indvar.i24
326        %t4 = load double, double* %t3
327        %t5 = fmul double %t4, 2.3
328        store double %t5, double* %t3
329        %t6 = getelementptr double, double* %d, i64 %indvar
330        %t7 = load double, double* %t6
331        %t8 = fmul double %t7, 4.5
332        store double %t8, double* %t6
333        %indvar.next = sub i64 %indvar, 1
334        %exitcond = icmp eq i64 %indvar.next, 10
335        br i1 %exitcond, label %return, label %loop
336
337return:
338        ret void
339}
340
341define void @another_count_up_signed(double* %d, i64 %n) nounwind {
342; CHECK-LABEL: another_count_up_signed:
343; CHECK:       # %bb.0: # %entry
344; CHECK-NEXT:    xorl %r8d, %r8d
345; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
346; CHECK-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
347; CHECK-NEXT:    movsd {{.*#+}} xmm2 = mem[0],zero
348; CHECK-NEXT:    xorl %ecx, %ecx
349; CHECK-NEXT:    movq %rdi, %rdx
350; CHECK-NEXT:    .p2align 4, 0x90
351; CHECK-NEXT:  .LBB6_1: # %loop
352; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
353; CHECK-NEXT:    movq %r8, %rax
354; CHECK-NEXT:    sarq $8, %rax
355; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
356; CHECK-NEXT:    mulsd %xmm0, %xmm3
357; CHECK-NEXT:    movsd %xmm3, (%rdi,%rax,8)
358; CHECK-NEXT:    movq %rcx, %rax
359; CHECK-NEXT:    sarq $24, %rax
360; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
361; CHECK-NEXT:    mulsd %xmm1, %xmm3
362; CHECK-NEXT:    movsd %xmm3, (%rdi,%rax,8)
363; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
364; CHECK-NEXT:    mulsd %xmm2, %xmm3
365; CHECK-NEXT:    movsd %xmm3, (%rdx)
366; CHECK-NEXT:    addq $8, %rdx
367; CHECK-NEXT:    addq $16777216, %rcx # imm = 0x1000000
368; CHECK-NEXT:    addq $256, %r8 # imm = 0x100
369; CHECK-NEXT:    decq %rsi
370; CHECK-NEXT:    jne .LBB6_1
371; CHECK-NEXT:  # %bb.2: # %return
372; CHECK-NEXT:    retq
373entry:
374        br label %loop
375
376loop:
377        %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop ]
378        %s0 = shl i64 %indvar, 8
379        %indvar.i8 = ashr i64 %s0, 8
380        %t0 = getelementptr double, double* %d, i64 %indvar.i8
381        %t1 = load double, double* %t0
382        %t2 = fmul double %t1, 0.1
383        store double %t2, double* %t0
384        %s1 = shl i64 %indvar, 24
385        %indvar.i24 = ashr i64 %s1, 24
386        %t3 = getelementptr double, double* %d, i64 %indvar.i24
387        %t4 = load double, double* %t3
388        %t5 = fmul double %t4, 2.3
389        store double %t5, double* %t3
390        %t6 = getelementptr double, double* %d, i64 %indvar
391        %t7 = load double, double* %t6
392        %t8 = fmul double %t7, 4.5
393        store double %t8, double* %t6
394        %indvar.next = add i64 %indvar, 1
395        %exitcond = icmp eq i64 %indvar.next, %n
396        br i1 %exitcond, label %return, label %loop
397
398return:
399        ret void
400}
401
402define void @another_count_down_signed(double* %d, i64 %n) nounwind {
403; CHECK-LABEL: another_count_down_signed:
404; CHECK:       # %bb.0: # %entry
405; CHECK-NEXT:    leaq -10(%rsi), %rax
406; CHECK-NEXT:    movq %rsi, %rcx
407; CHECK-NEXT:    shlq $24, %rcx
408; CHECK-NEXT:    shlq $8, %rsi
409; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
410; CHECK-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
411; CHECK-NEXT:    movsd {{.*#+}} xmm2 = mem[0],zero
412; CHECK-NEXT:    .p2align 4, 0x90
413; CHECK-NEXT:  .LBB7_1: # %loop
414; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
415; CHECK-NEXT:    movq %rsi, %rdx
416; CHECK-NEXT:    sarq $8, %rdx
417; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
418; CHECK-NEXT:    mulsd %xmm0, %xmm3
419; CHECK-NEXT:    movsd %xmm3, (%rdi,%rdx,8)
420; CHECK-NEXT:    movq %rcx, %rdx
421; CHECK-NEXT:    sarq $24, %rdx
422; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
423; CHECK-NEXT:    mulsd %xmm1, %xmm3
424; CHECK-NEXT:    movsd %xmm3, (%rdi,%rdx,8)
425; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
426; CHECK-NEXT:    mulsd %xmm2, %xmm3
427; CHECK-NEXT:    movsd %xmm3, 80(%rdi,%rax,8)
428; CHECK-NEXT:    addq $-16777216, %rcx # imm = 0xFF000000
429; CHECK-NEXT:    addq $-256, %rsi
430; CHECK-NEXT:    decq %rax
431; CHECK-NEXT:    jne .LBB7_1
432; CHECK-NEXT:  # %bb.2: # %return
433; CHECK-NEXT:    retq
434entry:
435        br label %loop
436
437loop:
438        %indvar = phi i64 [ %n, %entry ], [ %indvar.next, %loop ]
439        %s0 = shl i64 %indvar, 8
440        %indvar.i8 = ashr i64 %s0, 8
441        %t0 = getelementptr double, double* %d, i64 %indvar.i8
442        %t1 = load double, double* %t0
443        %t2 = fmul double %t1, 0.1
444        store double %t2, double* %t0
445        %s1 = shl i64 %indvar, 24
446        %indvar.i24 = ashr i64 %s1, 24
447        %t3 = getelementptr double, double* %d, i64 %indvar.i24
448        %t4 = load double, double* %t3
449        %t5 = fmul double %t4, 2.3
450        store double %t5, double* %t3
451        %t6 = getelementptr double, double* %d, i64 %indvar
452        %t7 = load double, double* %t6
453        %t8 = fmul double %t7, 4.5
454        store double %t8, double* %t6
455        %indvar.next = sub i64 %indvar, 1
456        %exitcond = icmp eq i64 %indvar.next, 10
457        br i1 %exitcond, label %return, label %loop
458
459return:
460        ret void
461}
462
463define void @yet_another_count_down(double* %d, i64 %n) nounwind {
464; CHECK-LABEL: yet_another_count_down:
465; CHECK:       # %bb.0: # %entry
466; CHECK-NEXT:    movq $-2040, %rax # imm = 0xF808
467; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
468; CHECK-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
469; CHECK-NEXT:    movsd {{.*#+}} xmm2 = mem[0],zero
470; CHECK-NEXT:    movq %rdi, %rcx
471; CHECK-NEXT:    movq %rdi, %rdx
472; CHECK-NEXT:    .p2align 4, 0x90
473; CHECK-NEXT:  .LBB8_1: # %loop
474; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
475; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
476; CHECK-NEXT:    mulsd %xmm0, %xmm3
477; CHECK-NEXT:    movsd %xmm3, 2040(%rdi,%rax)
478; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
479; CHECK-NEXT:    mulsd %xmm1, %xmm3
480; CHECK-NEXT:    movsd %xmm3, (%rcx)
481; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
482; CHECK-NEXT:    mulsd %xmm2, %xmm3
483; CHECK-NEXT:    movsd %xmm3, (%rdx)
484; CHECK-NEXT:    addq $-8, %rdx
485; CHECK-NEXT:    addq $134217720, %rcx # imm = 0x7FFFFF8
486; CHECK-NEXT:    addq $2040, %rax # imm = 0x7F8
487; CHECK-NEXT:    jne .LBB8_1
488; CHECK-NEXT:  # %bb.2: # %return
489; CHECK-NEXT:    retq
490entry:
491	br label %loop
492
493loop:
494	%indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop ]
495	%indvar.i8 = and i64 %indvar, 255
496	%t0 = getelementptr double, double* %d, i64 %indvar.i8
497	%t1 = load double, double* %t0
498	%t2 = fmul double %t1, 0.1
499	store double %t2, double* %t0
500	%indvar.i24 = and i64 %indvar, 16777215
501	%t3 = getelementptr double, double* %d, i64 %indvar.i24
502	%t4 = load double, double* %t3
503	%t5 = fmul double %t4, 2.3
504	store double %t5, double* %t3
505	%t6 = getelementptr double, double* %d, i64 %indvar
506	%t7 = load double, double* %t6
507	%t8 = fmul double %t7, 4.5
508	store double %t8, double* %t6
509	%indvar.next = sub i64 %indvar, 1
510	%exitcond = icmp eq i64 %indvar.next, 18446744073709551615
511	br i1 %exitcond, label %return, label %loop
512
513return:
514	ret void
515}
516
517define void @yet_another_count_up(double* %d, i64 %n) nounwind {
518; CHECK-LABEL: yet_another_count_up:
519; CHECK:       # %bb.0: # %entry
520; CHECK-NEXT:    xorl %eax, %eax
521; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
522; CHECK-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
523; CHECK-NEXT:    movsd {{.*#+}} xmm2 = mem[0],zero
524; CHECK-NEXT:    .p2align 4, 0x90
525; CHECK-NEXT:  .LBB9_1: # %loop
526; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
527; CHECK-NEXT:    movzbl %al, %ecx
528; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
529; CHECK-NEXT:    mulsd %xmm0, %xmm3
530; CHECK-NEXT:    movsd %xmm3, (%rdi,%rcx,8)
531; CHECK-NEXT:    movl %eax, %ecx
532; CHECK-NEXT:    andl $16777215, %ecx # imm = 0xFFFFFF
533; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
534; CHECK-NEXT:    mulsd %xmm1, %xmm3
535; CHECK-NEXT:    movsd %xmm3, (%rdi,%rcx,8)
536; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
537; CHECK-NEXT:    mulsd %xmm2, %xmm3
538; CHECK-NEXT:    movsd %xmm3, (%rdi,%rax,8)
539; CHECK-NEXT:    addq $3, %rax
540; CHECK-NEXT:    cmpq $10, %rax
541; CHECK-NEXT:    jne .LBB9_1
542; CHECK-NEXT:  # %bb.2: # %return
543; CHECK-NEXT:    retq
544entry:
545        br label %loop
546
547loop:
548        %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop ]
549        %indvar.i8 = and i64 %indvar, 255
550        %t0 = getelementptr double, double* %d, i64 %indvar.i8
551        %t1 = load double, double* %t0
552        %t2 = fmul double %t1, 0.1
553        store double %t2, double* %t0
554        %indvar.i24 = and i64 %indvar, 16777215
555        %t3 = getelementptr double, double* %d, i64 %indvar.i24
556        %t4 = load double, double* %t3
557        %t5 = fmul double %t4, 2.3
558        store double %t5, double* %t3
559        %t6 = getelementptr double, double* %d, i64 %indvar
560        %t7 = load double, double* %t6
561        %t8 = fmul double %t7, 4.5
562        store double %t8, double* %t6
563        %indvar.next = add i64 %indvar, 3
564        %exitcond = icmp eq i64 %indvar.next, 10
565        br i1 %exitcond, label %return, label %loop
566
567return:
568        ret void
569}
570
571define void @still_another_count_down(double* %d, i64 %n) nounwind {
572; CHECK-LABEL: still_another_count_down:
573; CHECK:       # %bb.0: # %entry
574; CHECK-NEXT:    movl $10, %eax
575; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
576; CHECK-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
577; CHECK-NEXT:    movsd {{.*#+}} xmm2 = mem[0],zero
578; CHECK-NEXT:    .p2align 4, 0x90
579; CHECK-NEXT:  .LBB10_1: # %loop
580; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
581; CHECK-NEXT:    movzbl %al, %ecx
582; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
583; CHECK-NEXT:    mulsd %xmm0, %xmm3
584; CHECK-NEXT:    movsd %xmm3, (%rdi,%rcx,8)
585; CHECK-NEXT:    movl %eax, %ecx
586; CHECK-NEXT:    andl $16777215, %ecx # imm = 0xFFFFFF
587; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
588; CHECK-NEXT:    mulsd %xmm1, %xmm3
589; CHECK-NEXT:    movsd %xmm3, (%rdi,%rcx,8)
590; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
591; CHECK-NEXT:    mulsd %xmm2, %xmm3
592; CHECK-NEXT:    movsd %xmm3, (%rdi,%rax,8)
593; CHECK-NEXT:    addq $-3, %rax
594; CHECK-NEXT:    jne .LBB10_1
595; CHECK-NEXT:  # %bb.2: # %return
596; CHECK-NEXT:    retq
597entry:
598        br label %loop
599
600loop:
601        %indvar = phi i64 [ 10, %entry ], [ %indvar.next, %loop ]
602        %indvar.i8 = and i64 %indvar, 255
603        %t0 = getelementptr double, double* %d, i64 %indvar.i8
604        %t1 = load double, double* %t0
605        %t2 = fmul double %t1, 0.1
606        store double %t2, double* %t0
607        %indvar.i24 = and i64 %indvar, 16777215
608        %t3 = getelementptr double, double* %d, i64 %indvar.i24
609        %t4 = load double, double* %t3
610        %t5 = fmul double %t4, 2.3
611        store double %t5, double* %t3
612        %t6 = getelementptr double, double* %d, i64 %indvar
613        %t7 = load double, double* %t6
614        %t8 = fmul double %t7, 4.5
615        store double %t8, double* %t6
616        %indvar.next = sub i64 %indvar, 3
617        %exitcond = icmp eq i64 %indvar.next, 0
618        br i1 %exitcond, label %return, label %loop
619
620return:
621        ret void
622}
623
624define void @yet_another_count_up_signed(double* %d, i64 %n) nounwind {
625; CHECK-LABEL: yet_another_count_up_signed:
626; CHECK:       # %bb.0: # %entry
627; CHECK-NEXT:    movq $-10, %rax
628; CHECK-NEXT:    xorl %ecx, %ecx
629; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
630; CHECK-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
631; CHECK-NEXT:    movsd {{.*#+}} xmm2 = mem[0],zero
632; CHECK-NEXT:    xorl %edx, %edx
633; CHECK-NEXT:    .p2align 4, 0x90
634; CHECK-NEXT:  .LBB11_1: # %loop
635; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
636; CHECK-NEXT:    movq %rcx, %rsi
637; CHECK-NEXT:    sarq $8, %rsi
638; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
639; CHECK-NEXT:    mulsd %xmm0, %xmm3
640; CHECK-NEXT:    movsd %xmm3, (%rdi,%rsi,8)
641; CHECK-NEXT:    movq %rdx, %rsi
642; CHECK-NEXT:    sarq $24, %rsi
643; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
644; CHECK-NEXT:    mulsd %xmm1, %xmm3
645; CHECK-NEXT:    movsd %xmm3, (%rdi,%rsi,8)
646; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
647; CHECK-NEXT:    mulsd %xmm2, %xmm3
648; CHECK-NEXT:    movsd %xmm3, 80(%rdi,%rax,8)
649; CHECK-NEXT:    addq $50331648, %rdx # imm = 0x3000000
650; CHECK-NEXT:    addq $768, %rcx # imm = 0x300
651; CHECK-NEXT:    addq $3, %rax
652; CHECK-NEXT:    jne .LBB11_1
653; CHECK-NEXT:  # %bb.2: # %return
654; CHECK-NEXT:    retq
655entry:
656        br label %loop
657
658loop:
659        %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop ]
660        %s0 = shl i64 %indvar, 8
661        %indvar.i8 = ashr i64 %s0, 8
662        %t0 = getelementptr double, double* %d, i64 %indvar.i8
663        %t1 = load double, double* %t0
664        %t2 = fmul double %t1, 0.1
665        store double %t2, double* %t0
666        %s1 = shl i64 %indvar, 24
667        %indvar.i24 = ashr i64 %s1, 24
668        %t3 = getelementptr double, double* %d, i64 %indvar.i24
669        %t4 = load double, double* %t3
670        %t5 = fmul double %t4, 2.3
671        store double %t5, double* %t3
672        %t6 = getelementptr double, double* %d, i64 %indvar
673        %t7 = load double, double* %t6
674        %t8 = fmul double %t7, 4.5
675        store double %t8, double* %t6
676        %indvar.next = add i64 %indvar, 3
677        %exitcond = icmp eq i64 %indvar.next, 10
678        br i1 %exitcond, label %return, label %loop
679
680return:
681        ret void
682}
683
684define void @yet_another_count_down_signed(double* %d, i64 %n) nounwind {
685; CHECK-LABEL: yet_another_count_down_signed:
686; CHECK:       # %bb.0: # %entry
687; CHECK-NEXT:    movl $10, %eax
688; CHECK-NEXT:    movl $167772160, %ecx # imm = 0xA000000
689; CHECK-NEXT:    movl $2560, %edx # imm = 0xA00
690; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
691; CHECK-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
692; CHECK-NEXT:    movsd {{.*#+}} xmm2 = mem[0],zero
693; CHECK-NEXT:    .p2align 4, 0x90
694; CHECK-NEXT:  .LBB12_1: # %loop
695; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
696; CHECK-NEXT:    movq %rdx, %rsi
697; CHECK-NEXT:    sarq $8, %rsi
698; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
699; CHECK-NEXT:    mulsd %xmm0, %xmm3
700; CHECK-NEXT:    movsd %xmm3, (%rdi,%rsi,8)
701; CHECK-NEXT:    movq %rcx, %rsi
702; CHECK-NEXT:    sarq $24, %rsi
703; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
704; CHECK-NEXT:    mulsd %xmm1, %xmm3
705; CHECK-NEXT:    movsd %xmm3, (%rdi,%rsi,8)
706; CHECK-NEXT:    movsd {{.*#+}} xmm3 = mem[0],zero
707; CHECK-NEXT:    mulsd %xmm2, %xmm3
708; CHECK-NEXT:    movsd %xmm3, (%rdi,%rax,8)
709; CHECK-NEXT:    addq $-50331648, %rcx # imm = 0xFD000000
710; CHECK-NEXT:    addq $-768, %rdx # imm = 0xFD00
711; CHECK-NEXT:    addq $-3, %rax
712; CHECK-NEXT:    jne .LBB12_1
713; CHECK-NEXT:  # %bb.2: # %return
714; CHECK-NEXT:    retq
715entry:
716        br label %loop
717
718loop:
719        %indvar = phi i64 [ 10, %entry ], [ %indvar.next, %loop ]
720        %s0 = shl i64 %indvar, 8
721        %indvar.i8 = ashr i64 %s0, 8
722        %t0 = getelementptr double, double* %d, i64 %indvar.i8
723        %t1 = load double, double* %t0
724        %t2 = fmul double %t1, 0.1
725        store double %t2, double* %t0
726        %s1 = shl i64 %indvar, 24
727        %indvar.i24 = ashr i64 %s1, 24
728        %t3 = getelementptr double, double* %d, i64 %indvar.i24
729        %t4 = load double, double* %t3
730        %t5 = fmul double %t4, 2.3
731        store double %t5, double* %t3
732        %t6 = getelementptr double, double* %d, i64 %indvar
733        %t7 = load double, double* %t6
734        %t8 = fmul double %t7, 4.5
735        store double %t8, double* %t6
736        %indvar.next = sub i64 %indvar, 3
737        %exitcond = icmp eq i64 %indvar.next, 0
738        br i1 %exitcond, label %return, label %loop
739
740return:
741        ret void
742}
743
744
745
746