1; RUN: llc -ppc-asm-full-reg-names -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr9 < %s | FileCheck %s
2
3; test_no_prep:
4; unsigned long test_no_prep(char *p, int count) {
5;   unsigned long i=0, res=0;
6;   int DISP1 = 4001;
7;   int DISP2 = 4002;
8;   int DISP3 = 4003;
9;   int DISP4 = 4004;
10;   for (; i < count ; i++) {
11;     unsigned long x1 = *(unsigned long *)(p + i + DISP1);
12;     unsigned long x2 = *(unsigned long *)(p + i + DISP2);
13;     unsigned long x3 = *(unsigned long *)(p + i + DISP3);
14;     unsigned long x4 = *(unsigned long *)(p + i + DISP4);
15;     res += x1*x2*x3*x4;
16;   }
17;   return res + count;
18; }
19
20define i64 @test_no_prep(i8* %0, i32 signext %1) {
21; CHECK-LABEL: test_no_prep:
22; CHECK:         addi r3, r3, 4004
23; CHECK:       .LBB0_2: #
24; CHECK-NEXT:    ldx r9, r3, r6
25; CHECK-NEXT:    ldx r10, r3, r7
26; CHECK-NEXT:    mulld r9, r10, r9
27; CHECK-NEXT:    ldx r11, r3, r8
28; CHECK-NEXT:    mulld r9, r9, r11
29; CHECK-NEXT:    ld r12, 0(r3)
30; CHECK-NEXT:    addi r3, r3, 1
31; CHECK-NEXT:    maddld r5, r9, r12, r5
32; CHECK-NEXT:    bdnz .LBB0_2
33  %3 = sext i32 %1 to i64
34  %4 = icmp eq i32 %1, 0
35  br i1 %4, label %27, label %5
36
375:                                                ; preds = %2, %5
38  %6 = phi i64 [ %25, %5 ], [ 0, %2 ]
39  %7 = phi i64 [ %24, %5 ], [ 0, %2 ]
40  %8 = getelementptr inbounds i8, i8* %0, i64 %6
41  %9 = getelementptr inbounds i8, i8* %8, i64 4001
42  %10 = bitcast i8* %9 to i64*
43  %11 = load i64, i64* %10, align 8
44  %12 = getelementptr inbounds i8, i8* %8, i64 4002
45  %13 = bitcast i8* %12 to i64*
46  %14 = load i64, i64* %13, align 8
47  %15 = getelementptr inbounds i8, i8* %8, i64 4003
48  %16 = bitcast i8* %15 to i64*
49  %17 = load i64, i64* %16, align 8
50  %18 = getelementptr inbounds i8, i8* %8, i64 4004
51  %19 = bitcast i8* %18 to i64*
52  %20 = load i64, i64* %19, align 8
53  %21 = mul i64 %14, %11
54  %22 = mul i64 %21, %17
55  %23 = mul i64 %22, %20
56  %24 = add i64 %23, %7
57  %25 = add nuw i64 %6, 1
58  %26 = icmp ult i64 %25, %3
59  br i1 %26, label %5, label %27
60
6127:                                               ; preds = %5, %2
62  %28 = phi i64 [ 0, %2 ], [ %24, %5 ]
63  %29 = add i64 %28, %3
64  ret i64 %29
65}
66
67; test_ds_prep:
68; unsigned long test_ds_prep(char *p, int count) {
69;   unsigned long i=0, res=0;
70;   int DISP1 = 4001;
71;   int DISP2 = 4002;
72;   int DISP3 = 4003;
73;   int DISP4 = 4006;
74;   for (; i < count ; i++) {
75;     unsigned long x1 = *(unsigned long *)(p + i + DISP1);
76;     unsigned long x2 = *(unsigned long *)(p + i + DISP2);
77;     unsigned long x3 = *(unsigned long *)(p + i + DISP3);
78;     unsigned long x4 = *(unsigned long *)(p + i + DISP4);
79;     res += x1*x2*x3*x4;
80;   }
81;   return res + count;
82; }
83
84define i64 @test_ds_prep(i8* %0, i32 signext %1) {
85; CHECK-LABEL: test_ds_prep:
86; CHECK:         addi r6, r3, 4002
87; CHECK:       .LBB1_2: #
88; CHECK-NEXT:    ldx r9, r6, r7
89; CHECK-NEXT:    ld r10, 0(r6)
90; CHECK-NEXT:    mulld r9, r10, r9
91; CHECK-NEXT:    ldx r11, r6, r5
92; CHECK-NEXT:    mulld r9, r9, r11
93; CHECK-NEXT:    addi r8, r6, 1
94; CHECK-NEXT:    ld r6, 4(r6)
95; CHECK-NEXT:    maddld r3, r9, r6, r3
96; CHECK-NEXT:    mr r6, r8
97; CHECK-NEXT:    bdnz .LBB1_2
98  %3 = sext i32 %1 to i64
99  %4 = icmp eq i32 %1, 0
100  br i1 %4, label %27, label %5
101
1025:                                                ; preds = %2, %5
103  %6 = phi i64 [ %25, %5 ], [ 0, %2 ]
104  %7 = phi i64 [ %24, %5 ], [ 0, %2 ]
105  %8 = getelementptr inbounds i8, i8* %0, i64 %6
106  %9 = getelementptr inbounds i8, i8* %8, i64 4001
107  %10 = bitcast i8* %9 to i64*
108  %11 = load i64, i64* %10, align 8
109  %12 = getelementptr inbounds i8, i8* %8, i64 4002
110  %13 = bitcast i8* %12 to i64*
111  %14 = load i64, i64* %13, align 8
112  %15 = getelementptr inbounds i8, i8* %8, i64 4003
113  %16 = bitcast i8* %15 to i64*
114  %17 = load i64, i64* %16, align 8
115  %18 = getelementptr inbounds i8, i8* %8, i64 4006
116  %19 = bitcast i8* %18 to i64*
117  %20 = load i64, i64* %19, align 8
118  %21 = mul i64 %14, %11
119  %22 = mul i64 %21, %17
120  %23 = mul i64 %22, %20
121  %24 = add i64 %23, %7
122  %25 = add nuw i64 %6, 1
123  %26 = icmp ult i64 %25, %3
124  br i1 %26, label %5, label %27
125
12627:                                               ; preds = %5, %2
127  %28 = phi i64 [ 0, %2 ], [ %24, %5 ]
128  %29 = add i64 %28, %3
129  ret i64 %29
130}
131
132; test_max_number_reminder:
133; unsigned long test_max_number_reminder(char *p, int count) {
134;  unsigned long i=0, res=0;
135;  int DISP1 = 4001;
136;  int DISP2 = 4002;
137;  int DISP3 = 4003;
138;  int DISP4 = 4005;
139;  int DISP5 = 4006;
140;  int DISP6 = 4007;
141;  int DISP7 = 4014;
142;  int DISP8 = 4010;
143;  int DISP9 = 4011;
144;  for (; i < count ; i++) {
145;    unsigned long x1 = *(unsigned long *)(p + i + DISP1);
146;    unsigned long x2 = *(unsigned long *)(p + i + DISP2);
147;    unsigned long x3 = *(unsigned long *)(p + i + DISP3);
148;    unsigned long x4 = *(unsigned long *)(p + i + DISP4);
149;    unsigned long x5 = *(unsigned long *)(p + i + DISP5);
150;    unsigned long x6 = *(unsigned long *)(p + i + DISP6);
151;    unsigned long x7 = *(unsigned long *)(p + i + DISP7);
152;    unsigned long x8 = *(unsigned long *)(p + i + DISP8);
153;    unsigned long x9 = *(unsigned long *)(p + i + DISP9);
154;    res += x1*x2*x3*x4*x5*x6*x7*x8*x9;
155;  }
156;  return res + count;
157;}
158
159define i64 @test_max_number_reminder(i8* %0, i32 signext %1) {
160; CHECK-LABEL: test_max_number_reminder:
161; CHECK:         addi r9, r3, 4002
162; CHECK:       .LBB2_2: #
163; CHECK-NEXT:    ldx r12, r9, r6
164; CHECK-NEXT:    ld r0, 0(r9)
165; CHECK-NEXT:    mulld r12, r0, r12
166; CHECK-NEXT:    addi r11, r9, 1
167; CHECK-NEXT:    ldx r30, r9, r7
168; CHECK-NEXT:    ld r29, 4(r9)
169; CHECK-NEXT:    ldx r28, r9, r8
170; CHECK-NEXT:    ld r27, 12(r9)
171; CHECK-NEXT:    ld r26, 8(r9)
172; CHECK-NEXT:    ldx r25, r9, r10
173; CHECK-NEXT:    ldx r9, r9, r5
174; CHECK-NEXT:    mulld r9, r12, r9
175; CHECK-NEXT:    mulld r9, r9, r30
176; CHECK-NEXT:    mulld r9, r9, r29
177; CHECK-NEXT:    mulld r9, r9, r28
178; CHECK-NEXT:    mulld r9, r9, r27
179; CHECK-NEXT:    mulld r9, r9, r26
180; CHECK-NEXT:    maddld r3, r9, r25, r3
181; CHECK-NEXT:    mr r9, r11
182; CHECK-NEXT:    bdnz .LBB2_2
183  %3 = sext i32 %1 to i64
184  %4 = icmp eq i32 %1, 0
185  br i1 %4, label %47, label %5
186
1875:                                                ; preds = %2, %5
188  %6 = phi i64 [ %45, %5 ], [ 0, %2 ]
189  %7 = phi i64 [ %44, %5 ], [ 0, %2 ]
190  %8 = getelementptr inbounds i8, i8* %0, i64 %6
191  %9 = getelementptr inbounds i8, i8* %8, i64 4001
192  %10 = bitcast i8* %9 to i64*
193  %11 = load i64, i64* %10, align 8
194  %12 = getelementptr inbounds i8, i8* %8, i64 4002
195  %13 = bitcast i8* %12 to i64*
196  %14 = load i64, i64* %13, align 8
197  %15 = getelementptr inbounds i8, i8* %8, i64 4003
198  %16 = bitcast i8* %15 to i64*
199  %17 = load i64, i64* %16, align 8
200  %18 = getelementptr inbounds i8, i8* %8, i64 4005
201  %19 = bitcast i8* %18 to i64*
202  %20 = load i64, i64* %19, align 8
203  %21 = getelementptr inbounds i8, i8* %8, i64 4006
204  %22 = bitcast i8* %21 to i64*
205  %23 = load i64, i64* %22, align 8
206  %24 = getelementptr inbounds i8, i8* %8, i64 4007
207  %25 = bitcast i8* %24 to i64*
208  %26 = load i64, i64* %25, align 8
209  %27 = getelementptr inbounds i8, i8* %8, i64 4014
210  %28 = bitcast i8* %27 to i64*
211  %29 = load i64, i64* %28, align 8
212  %30 = getelementptr inbounds i8, i8* %8, i64 4010
213  %31 = bitcast i8* %30 to i64*
214  %32 = load i64, i64* %31, align 8
215  %33 = getelementptr inbounds i8, i8* %8, i64 4011
216  %34 = bitcast i8* %33 to i64*
217  %35 = load i64, i64* %34, align 8
218  %36 = mul i64 %14, %11
219  %37 = mul i64 %36, %17
220  %38 = mul i64 %37, %20
221  %39 = mul i64 %38, %23
222  %40 = mul i64 %39, %26
223  %41 = mul i64 %40, %29
224  %42 = mul i64 %41, %32
225  %43 = mul i64 %42, %35
226  %44 = add i64 %43, %7
227  %45 = add nuw i64 %6, 1
228  %46 = icmp ult i64 %45, %3
229  br i1 %46, label %5, label %47
230
23147:                                               ; preds = %5, %2
232  %48 = phi i64 [ 0, %2 ], [ %44, %5 ]
233  %49 = add i64 %48, %3
234  ret i64 %49
235}
236
237; test_update_ds_prep_interact:
238; unsigned long test_update_ds_prep_interact(char *p, int count) {
239;   unsigned long i=0, res=0;
240;   int DISP1 = 4001;
241;   int DISP2 = 4002;
242;   int DISP3 = 4003;
243;   int DISP4 = 4006;
244;   for (; i < count ; i++) {
245;     unsigned long x1 = *(unsigned long *)(p + 4 * i + DISP1);
246;     unsigned long x2 = *(unsigned long *)(p + 4 * i + DISP2);
247;     unsigned long x3 = *(unsigned long *)(p + 4 * i + DISP3);
248;     unsigned long x4 = *(unsigned long *)(p + 4 * i + DISP4);
249;     res += x1*x2*x3*x4;
250;   }
251;   return res + count;
252; }
253
254define dso_local i64 @test_update_ds_prep_interact(i8* %0, i32 signext %1) {
255; CHECK-LABEL: test_update_ds_prep_interact:
256; CHECK:         addi r3, r3, 3998
257; CHECK:       .LBB3_2: #
258; CHECK-NEXT:    ldu r8, 4(r3)
259; CHECK-NEXT:    ldx r9, r3, r7
260; CHECK-NEXT:    mulld r8, r8, r9
261; CHECK-NEXT:    ldx r10, r3, r6
262; CHECK-NEXT:    mulld r8, r8, r10
263; CHECK-NEXT:    ld r11, 4(r3)
264; CHECK-NEXT:    maddld r5, r8, r11, r5
265; CHECK-NEXT:    bdnz .LBB3_2
266  %3 = sext i32 %1 to i64
267  %4 = icmp eq i32 %1, 0
268  br i1 %4, label %28, label %5
269
2705:                                                ; preds = %2, %5
271  %6 = phi i64 [ %26, %5 ], [ 0, %2 ]
272  %7 = phi i64 [ %25, %5 ], [ 0, %2 ]
273  %8 = shl i64 %6, 2
274  %9 = getelementptr inbounds i8, i8* %0, i64 %8
275  %10 = getelementptr inbounds i8, i8* %9, i64 4001
276  %11 = bitcast i8* %10 to i64*
277  %12 = load i64, i64* %11, align 8
278  %13 = getelementptr inbounds i8, i8* %9, i64 4002
279  %14 = bitcast i8* %13 to i64*
280  %15 = load i64, i64* %14, align 8
281  %16 = getelementptr inbounds i8, i8* %9, i64 4003
282  %17 = bitcast i8* %16 to i64*
283  %18 = load i64, i64* %17, align 8
284  %19 = getelementptr inbounds i8, i8* %9, i64 4006
285  %20 = bitcast i8* %19 to i64*
286  %21 = load i64, i64* %20, align 8
287  %22 = mul i64 %15, %12
288  %23 = mul i64 %22, %18
289  %24 = mul i64 %23, %21
290  %25 = add i64 %24, %7
291  %26 = add nuw i64 %6, 1
292  %27 = icmp ult i64 %26, %3
293  br i1 %27, label %5, label %28
294
29528:                                               ; preds = %5, %2
296  %29 = phi i64 [ 0, %2 ], [ %25, %5 ]
297  %30 = add i64 %29, %3
298  ret i64 %30
299}
300
301; test_update_ds_prep_nointeract:
302; unsigned long test_update_ds_prep_nointeract(char *p, int count) {
303;   unsigned long i=0, res=0;
304;   int DISP1 = 4001;
305;   int DISP2 = 4002;
306;   int DISP3 = 4003;
307;   int DISP4 = 4007;
308;   for (; i < count ; i++) {
309;     char x1 = *(p + i + DISP1);
310;     unsigned long x2 = *(unsigned long *)(p + i + DISP2);
311;     unsigned long x3 = *(unsigned long *)(p + i + DISP3);
312;     unsigned long x4 = *(unsigned long *)(p + i + DISP4);
313;     res += (unsigned long)x1*x2*x3*x4;
314;   }
315;   return res + count;
316; }
317
318define i64 @test_update_ds_prep_nointeract(i8* %0, i32 signext %1) {
319; CHECK-LABEL: test_update_ds_prep_nointeract:
320; CHECK:         addi r5, r3, 4000
321; CHECK:         addi r3, r3, 4003
322; CHECK:       .LBB4_2: #
323; CHECK-NEXT:    lbzu r8, 1(r5)
324; CHECK-NEXT:    ldx r9, r3, r7
325; CHECK-NEXT:    ld r10, 0(r3)
326; CHECK-NEXT:    ld r11, 4(r3)
327; CHECK-NEXT:    addi r3, r3, 1
328; CHECK-NEXT:    mulld r8, r9, r8
329; CHECK-NEXT:    mulld r8, r8, r10
330; CHECK-NEXT:    maddld r6, r8, r11, r6
331; CHECK-NEXT:    bdnz .LBB4_2
332  %3 = sext i32 %1 to i64
333  %4 = icmp eq i32 %1, 0
334  br i1 %4, label %27, label %5
335
3365:                                                ; preds = %2, %5
337  %6 = phi i64 [ %25, %5 ], [ 0, %2 ]
338  %7 = phi i64 [ %24, %5 ], [ 0, %2 ]
339  %8 = getelementptr inbounds i8, i8* %0, i64 %6
340  %9 = getelementptr inbounds i8, i8* %8, i64 4001
341  %10 = load i8, i8* %9, align 1
342  %11 = getelementptr inbounds i8, i8* %8, i64 4002
343  %12 = bitcast i8* %11 to i64*
344  %13 = load i64, i64* %12, align 8
345  %14 = getelementptr inbounds i8, i8* %8, i64 4003
346  %15 = bitcast i8* %14 to i64*
347  %16 = load i64, i64* %15, align 8
348  %17 = getelementptr inbounds i8, i8* %8, i64 4007
349  %18 = bitcast i8* %17 to i64*
350  %19 = load i64, i64* %18, align 8
351  %20 = zext i8 %10 to i64
352  %21 = mul i64 %13, %20
353  %22 = mul i64 %21, %16
354  %23 = mul i64 %22, %19
355  %24 = add i64 %23, %7
356  %25 = add nuw i64 %6, 1
357  %26 = icmp ult i64 %25, %3
358  br i1 %26, label %5, label %27
359
36027:                                               ; preds = %5, %2
361  %28 = phi i64 [ 0, %2 ], [ %24, %5 ]
362  %29 = add i64 %28, %3
363  ret i64 %29
364}
365
366; test_ds_multiple_chains:
367; unsigned long test_ds_multiple_chains(char *p, char *q, int count) {
368;   unsigned long i=0, res=0;
369;   int DISP1 = 4001;
370;   int DISP2 = 4010;
371;   int DISP3 = 4005;
372;   int DISP4 = 4009;
373;   for (; i < count ; i++) {
374;     unsigned long x1 = *(unsigned long *)(p + i + DISP1);
375;     unsigned long x2 = *(unsigned long *)(p + i + DISP2);
376;     unsigned long x3 = *(unsigned long *)(p + i + DISP3);
377;     unsigned long x4 = *(unsigned long *)(p + i + DISP4);
378;     unsigned long x5 = *(unsigned long *)(q + i + DISP1);
379;     unsigned long x6 = *(unsigned long *)(q + i + DISP2);
380;     unsigned long x7 = *(unsigned long *)(q + i + DISP3);
381;     unsigned long x8 = *(unsigned long *)(q + i + DISP4);
382;     res += x1*x2*x3*x4*x5*x6*x7*x8;
383;   }
384;   return res + count;
385; }
386
387define dso_local i64 @test_ds_multiple_chains(i8* %0, i8* %1, i32 signext %2) {
388; CHECK-LABEL: test_ds_multiple_chains:
389; CHECK:         addi r3, r3, 4001
390; CHECK:         addi r4, r4, 4001
391; CHECK:       .LBB5_2: #
392; CHECK-NEXT:    ld r8, 0(r3)
393; CHECK-NEXT:    ldx r9, r3, r7
394; CHECK-NEXT:    mulld r8, r9, r8
395; CHECK-NEXT:    ld r9, 4(r3)
396; CHECK-NEXT:    mulld r8, r8, r9
397; CHECK-NEXT:    ld r10, 8(r3)
398; CHECK-NEXT:    addi r3, r3, 1
399; CHECK-NEXT:    mulld r8, r8, r10
400; CHECK-NEXT:    ld r11, 0(r4)
401; CHECK-NEXT:    mulld r8, r8, r11
402; CHECK-NEXT:    ldx r12, r4, r7
403; CHECK-NEXT:    mulld r8, r8, r12
404; CHECK-NEXT:    ld r0, 4(r4)
405; CHECK-NEXT:    mulld r8, r8, r0
406; CHECK-NEXT:    ld r30, 8(r4)
407; CHECK-NEXT:    addi r4, r4, 1
408; CHECK-NEXT:    maddld r6, r8, r30, r6
409; CHECK-NEXT:    bdnz .LBB5_2
410  %4 = sext i32 %2 to i64
411  %5 = icmp eq i32 %2, 0
412  br i1 %5, label %45, label %6
413
4146:                                                ; preds = %3, %6
415  %7 = phi i64 [ %43, %6 ], [ 0, %3 ]
416  %8 = phi i64 [ %42, %6 ], [ 0, %3 ]
417  %9 = getelementptr inbounds i8, i8* %0, i64 %7
418  %10 = getelementptr inbounds i8, i8* %9, i64 4001
419  %11 = bitcast i8* %10 to i64*
420  %12 = load i64, i64* %11, align 8
421  %13 = getelementptr inbounds i8, i8* %9, i64 4010
422  %14 = bitcast i8* %13 to i64*
423  %15 = load i64, i64* %14, align 8
424  %16 = getelementptr inbounds i8, i8* %9, i64 4005
425  %17 = bitcast i8* %16 to i64*
426  %18 = load i64, i64* %17, align 8
427  %19 = getelementptr inbounds i8, i8* %9, i64 4009
428  %20 = bitcast i8* %19 to i64*
429  %21 = load i64, i64* %20, align 8
430  %22 = getelementptr inbounds i8, i8* %1, i64 %7
431  %23 = getelementptr inbounds i8, i8* %22, i64 4001
432  %24 = bitcast i8* %23 to i64*
433  %25 = load i64, i64* %24, align 8
434  %26 = getelementptr inbounds i8, i8* %22, i64 4010
435  %27 = bitcast i8* %26 to i64*
436  %28 = load i64, i64* %27, align 8
437  %29 = getelementptr inbounds i8, i8* %22, i64 4005
438  %30 = bitcast i8* %29 to i64*
439  %31 = load i64, i64* %30, align 8
440  %32 = getelementptr inbounds i8, i8* %22, i64 4009
441  %33 = bitcast i8* %32 to i64*
442  %34 = load i64, i64* %33, align 8
443  %35 = mul i64 %15, %12
444  %36 = mul i64 %35, %18
445  %37 = mul i64 %36, %21
446  %38 = mul i64 %37, %25
447  %39 = mul i64 %38, %28
448  %40 = mul i64 %39, %31
449  %41 = mul i64 %40, %34
450  %42 = add i64 %41, %8
451  %43 = add nuw i64 %7, 1
452  %44 = icmp ult i64 %43, %4
453  br i1 %44, label %6, label %45
454
45545:                                               ; preds = %6, %3
456  %46 = phi i64 [ 0, %3 ], [ %42, %6 ]
457  %47 = add i64 %46, %4
458  ret i64 %47
459}
460
461; test_ds_cross_basic_blocks:
462;extern char *arr;
463;unsigned long foo(char *p, int count)
464;{
465;  unsigned long i=0, res=0;
466;  int DISP1 = 4000;
467;  int DISP2 = 4001;
468;  int DISP3 = 4002;
469;  int DISP4 = 4003;
470;  int DISP5 = 4005;
471;  int DISP6 = 4009;
472;  unsigned long x1, x2, x3, x4, x5, x6;
473;  x1=x2=x3=x4=x5=x6=1;
474;  for (; i < count ; i++) {
475;    if (arr[i] % 3 == 1) {
476;      x1 += *(unsigned long *)(p + i + DISP1);
477;      x2 += *(unsigned long *)(p + i + DISP2);
478;    }
479;    else if (arr[i] % 3 == 2) {
480;      x3 += *(unsigned long *)(p + i + DISP3);
481;      x4 += *(unsigned long *)(p + i + DISP5);
482;    }
483;    else {
484;      x5 += *(unsigned long *)(p + i + DISP4);
485;      x6 += *(unsigned long *)(p + i + DISP6);
486;    }
487;    res += x1*x2*x3*x4*x5*x6;
488;  }
489;  return res;
490;}
491
492@arr = external local_unnamed_addr global i8*, align 8
493
494define i64 @test_ds_cross_basic_blocks(i8* %0, i32 signext %1) {
495; CHECK-LABEL: test_ds_cross_basic_blocks:
496; CHECK:         addi r6, r3, 4009
497; CHECK:       .LBB6_2: #
498; CHECK-NEXT:    ldx r0, r6, r8
499; CHECK-NEXT:    add r28, r0, r28
500; CHECK-NEXT:    ld r0, -8(r6)
501; CHECK-NEXT:    add r29, r0, r29
502; CHECK-NEXT:  .LBB6_3: #
503; CHECK-NEXT:    addi r6, r6, 1
504; CHECK-NEXT:    mulld r0, r29, r28
505; CHECK-NEXT:    mulld r0, r0, r30
506; CHECK-NEXT:    mulld r0, r0, r12
507; CHECK-NEXT:    mulld r0, r0, r11
508; CHECK-NEXT:    maddld r3, r0, r7, r3
509; CHECK-NEXT:    bdz .LBB6_9
510; CHECK-NEXT:  .LBB6_4: #
511; CHECK-NEXT:    lbzu r0, 1(r5)
512; CHECK-NEXT:    mulhwu r27, r0, r4
513; CHECK-NEXT:    rlwinm r26, r27, 0, 0, 30
514; CHECK-NEXT:    srwi r27, r27, 1
515; CHECK-NEXT:    add r27, r27, r26
516; CHECK-NEXT:    sub r0, r0, r27
517; CHECK-NEXT:    cmplwi r0, 1
518; CHECK-NEXT:    beq cr0, .LBB6_2
519; CHECK-NEXT:  # %bb.5: #
520; CHECK-NEXT:    clrlwi r0, r0, 24
521; CHECK-NEXT:    cmplwi r0, 2
522; CHECK-NEXT:    bne cr0, .LBB6_7
523; CHECK-NEXT:  # %bb.6: #
524; CHECK-NEXT:    ldx r0, r6, r9
525; CHECK-NEXT:    add r30, r0, r30
526; CHECK-NEXT:    ld r0, -4(r6)
527; CHECK-NEXT:    add r12, r0, r12
528; CHECK-NEXT:    b .LBB6_3
529; CHECK-NEXT:    .p2align 4
530; CHECK-NEXT:  .LBB6_7: #
531; CHECK-NEXT:    ldx r0, r6, r10
532; CHECK-NEXT:    add r11, r0, r11
533; CHECK-NEXT:    ld r0, 0(r6)
534; CHECK-NEXT:    add r7, r0, r7
535  %3 = sext i32 %1 to i64
536  %4 = icmp eq i32 %1, 0
537  br i1 %4, label %66, label %5
538
5395:                                                ; preds = %2
540  %6 = load i8*, i8** @arr, align 8
541  br label %7
542
5437:                                                ; preds = %5, %51
544  %8 = phi i64 [ 1, %5 ], [ %57, %51 ]
545  %9 = phi i64 [ 1, %5 ], [ %56, %51 ]
546  %10 = phi i64 [ 1, %5 ], [ %55, %51 ]
547  %11 = phi i64 [ 1, %5 ], [ %54, %51 ]
548  %12 = phi i64 [ 1, %5 ], [ %53, %51 ]
549  %13 = phi i64 [ 1, %5 ], [ %52, %51 ]
550  %14 = phi i64 [ 0, %5 ], [ %64, %51 ]
551  %15 = phi i64 [ 0, %5 ], [ %63, %51 ]
552  %16 = getelementptr inbounds i8, i8* %6, i64 %14
553  %17 = load i8, i8* %16, align 1
554  %18 = urem i8 %17, 3
555  %19 = icmp eq i8 %18, 1
556  br i1 %19, label %20, label %30
557
55820:                                               ; preds = %7
559  %21 = getelementptr inbounds i8, i8* %0, i64 %14
560  %22 = getelementptr inbounds i8, i8* %21, i64 4000
561  %23 = bitcast i8* %22 to i64*
562  %24 = load i64, i64* %23, align 8
563  %25 = add i64 %24, %13
564  %26 = getelementptr inbounds i8, i8* %21, i64 4001
565  %27 = bitcast i8* %26 to i64*
566  %28 = load i64, i64* %27, align 8
567  %29 = add i64 %28, %12
568  br label %51
569
57030:                                               ; preds = %7
571  %31 = icmp eq i8 %18, 2
572  %32 = getelementptr inbounds i8, i8* %0, i64 %14
573  br i1 %31, label %33, label %42
574
57533:                                               ; preds = %30
576  %34 = getelementptr inbounds i8, i8* %32, i64 4002
577  %35 = bitcast i8* %34 to i64*
578  %36 = load i64, i64* %35, align 8
579  %37 = add i64 %36, %11
580  %38 = getelementptr inbounds i8, i8* %32, i64 4005
581  %39 = bitcast i8* %38 to i64*
582  %40 = load i64, i64* %39, align 8
583  %41 = add i64 %40, %10
584  br label %51
585
58642:                                               ; preds = %30
587  %43 = getelementptr inbounds i8, i8* %32, i64 4003
588  %44 = bitcast i8* %43 to i64*
589  %45 = load i64, i64* %44, align 8
590  %46 = add i64 %45, %9
591  %47 = getelementptr inbounds i8, i8* %32, i64 4009
592  %48 = bitcast i8* %47 to i64*
593  %49 = load i64, i64* %48, align 8
594  %50 = add i64 %49, %8
595  br label %51
596
59751:                                               ; preds = %33, %42, %20
598  %52 = phi i64 [ %25, %20 ], [ %13, %33 ], [ %13, %42 ]
599  %53 = phi i64 [ %29, %20 ], [ %12, %33 ], [ %12, %42 ]
600  %54 = phi i64 [ %11, %20 ], [ %37, %33 ], [ %11, %42 ]
601  %55 = phi i64 [ %10, %20 ], [ %41, %33 ], [ %10, %42 ]
602  %56 = phi i64 [ %9, %20 ], [ %9, %33 ], [ %46, %42 ]
603  %57 = phi i64 [ %8, %20 ], [ %8, %33 ], [ %50, %42 ]
604  %58 = mul i64 %53, %52
605  %59 = mul i64 %58, %54
606  %60 = mul i64 %59, %55
607  %61 = mul i64 %60, %56
608  %62 = mul i64 %61, %57
609  %63 = add i64 %62, %15
610  %64 = add nuw i64 %14, 1
611  %65 = icmp ult i64 %64, %3
612  br i1 %65, label %7, label %66
613
61466:                                               ; preds = %51, %2
615  %67 = phi i64 [ 0, %2 ], [ %63, %51 ]
616  ret i64 %67
617}
618
619; test_ds_float:
620;float test_ds_float(char *p, int count) {
621;  int i=0 ;
622;  float res=0;
623;  int DISP1 = 4001;
624;  int DISP2 = 4002;
625;  int DISP3 = 4022;
626;  int DISP4 = 4062;
627;  for (; i < count ; i++) {
628;    float x1 = *(float *)(p + i + DISP1);
629;    float x2 = *(float *)(p + i + DISP2);
630;    float x3 = *(float *)(p + i + DISP3);
631;    float x4 = *(float *)(p + i + DISP4);
632;    res += x1*x2*x3*x4;
633;  }
634;  return res;
635;}
636
637define float @test_ds_float(i8* %0, i32 signext %1) {
638; CHECK-LABEL: test_ds_float:
639; CHECK:         addi r3, r3, 4002
640; CHECK:       .LBB7_2: #
641; CHECK-NEXT:    lfsx f0, r3, r4
642; CHECK-NEXT:    lfs f2, 0(r3)
643; CHECK-NEXT:    xsmulsp f0, f0, f2
644; CHECK-NEXT:    lfs f3, 20(r3)
645; CHECK-NEXT:    xsmulsp f0, f0, f3
646; CHECK-NEXT:    lfs f4, 60(r3)
647; CHECK-NEXT:    addi r3, r3, 1
648; CHECK-NEXT:    xsmulsp f0, f0, f4
649; CHECK-NEXT:    xsaddsp f1, f1, f0
650; CHECK-NEXT:    bdnz .LBB7_2
651  %3 = icmp sgt i32 %1, 0
652  br i1 %3, label %4, label %28
653
6544:                                                ; preds = %2
655  %5 = zext i32 %1 to i64
656  br label %6
657
6586:                                                ; preds = %6, %4
659  %7 = phi i64 [ 0, %4 ], [ %26, %6 ]
660  %8 = phi float [ 0.000000e+00, %4 ], [ %25, %6 ]
661  %9 = getelementptr inbounds i8, i8* %0, i64 %7
662  %10 = getelementptr inbounds i8, i8* %9, i64 4001
663  %11 = bitcast i8* %10 to float*
664  %12 = load float, float* %11, align 4
665  %13 = getelementptr inbounds i8, i8* %9, i64 4002
666  %14 = bitcast i8* %13 to float*
667  %15 = load float, float* %14, align 4
668  %16 = getelementptr inbounds i8, i8* %9, i64 4022
669  %17 = bitcast i8* %16 to float*
670  %18 = load float, float* %17, align 4
671  %19 = getelementptr inbounds i8, i8* %9, i64 4062
672  %20 = bitcast i8* %19 to float*
673  %21 = load float, float* %20, align 4
674  %22 = fmul float %12, %15
675  %23 = fmul float %22, %18
676  %24 = fmul float %23, %21
677  %25 = fadd float %8, %24
678  %26 = add nuw nsw i64 %7, 1
679  %27 = icmp eq i64 %26, %5
680  br i1 %27, label %28, label %6
681
68228:                                               ; preds = %6, %2
683  %29 = phi float [ 0.000000e+00, %2 ], [ %25, %6 ]
684  ret float %29
685}
686
687; test_ds_combine_float_int:
688;float test_ds_combine_float_int(char *p, int count) {
689;  int i=0 ;
690;  float res=0;
691;  int DISP1 = 4001;
692;  int DISP2 = 4002;
693;  int DISP3 = 4022;
694;  int DISP4 = 4062;
695;  for (; i < count ; i++) {
696;    float x1 = *(float *)(p + i + DISP1);
697;    unsigned long x2 = *(unsigned long*)(p + i + DISP2);
698;    float x3 = *(float *)(p + i + DISP3);
699;    float x4 = *(float *)(p + i + DISP4);
700;    res += x1*x2*x3*x4;
701;  }
702;  return res;
703;}
704
705define float @test_ds_combine_float_int(i8* %0, i32 signext %1) {
706; CHECK-LABEL: test_ds_combine_float_int:
707; CHECK:         addi r3, r3, 4002
708; CHECK:       .LBB8_2: #
709; CHECK-NEXT:    lfd f4, 0(r3)
710; CHECK-NEXT:    lfsx f0, r3, r4
711; CHECK-NEXT:    xscvuxdsp f4, f4
712; CHECK-NEXT:    lfs f2, 20(r3)
713; CHECK-NEXT:    xsmulsp f0, f0, f4
714; CHECK-NEXT:    xsmulsp f0, f2, f0
715; CHECK-NEXT:    lfs f3, 60(r3)
716; CHECK-NEXT:    addi r3, r3, 1
717; CHECK-NEXT:    xsmulsp f0, f3, f0
718; CHECK-NEXT:    xsaddsp f1, f1, f0
719; CHECK-NEXT:    bdnz .LBB8_2
720  %3 = icmp sgt i32 %1, 0
721  br i1 %3, label %4, label %29
722
7234:                                                ; preds = %2
724  %5 = zext i32 %1 to i64
725  br label %6
726
7276:                                                ; preds = %6, %4
728  %7 = phi i64 [ 0, %4 ], [ %27, %6 ]
729  %8 = phi float [ 0.000000e+00, %4 ], [ %26, %6 ]
730  %9 = getelementptr inbounds i8, i8* %0, i64 %7
731  %10 = getelementptr inbounds i8, i8* %9, i64 4001
732  %11 = bitcast i8* %10 to float*
733  %12 = load float, float* %11, align 4
734  %13 = getelementptr inbounds i8, i8* %9, i64 4002
735  %14 = bitcast i8* %13 to i64*
736  %15 = load i64, i64* %14, align 8
737  %16 = getelementptr inbounds i8, i8* %9, i64 4022
738  %17 = bitcast i8* %16 to float*
739  %18 = load float, float* %17, align 4
740  %19 = getelementptr inbounds i8, i8* %9, i64 4062
741  %20 = bitcast i8* %19 to float*
742  %21 = load float, float* %20, align 4
743  %22 = uitofp i64 %15 to float
744  %23 = fmul float %12, %22
745  %24 = fmul float %18, %23
746  %25 = fmul float %21, %24
747  %26 = fadd float %8, %25
748  %27 = add nuw nsw i64 %7, 1
749  %28 = icmp eq i64 %27, %5
750  br i1 %28, label %29, label %6
751
75229:                                               ; preds = %6, %2
753  %30 = phi float [ 0.000000e+00, %2 ], [ %26, %6 ]
754  ret float %30
755}
756
757; test_ds_lwa_prep:
758; long long test_ds_lwa_prep(char *p, int count) {
759;   long long i=0, res=0;
760;   int DISP1 = 4001;
761;   int DISP2 = 4002;
762;   int DISP3 = 4006;
763;   int DISP4 = 4010;
764;   for (; i < count ; i++) {
765;     long long x1 = *(int *)(p + i + DISP1);
766;     long long x2 = *(int *)(p + i + DISP2);
767;     long long x3 = *(int *)(p + i + DISP3);
768;     long long x4 = *(int *)(p + i + DISP4);
769;     res += x1*x2*x3*x4;
770;   }
771;   return res + count;
772; }
773
774define i64 @test_ds_lwa_prep(i8* %0, i32 signext %1) {
775; CHECK-LABEL: test_ds_lwa_prep:
776; CHECK:         addi r5, r3, 2
777; CHECK:         li r6, -1
778; CHECK:       .LBB9_2: #
779; CHECK-NEXT:    lwax r7, r5, r6
780; CHECK-NEXT:    lwa r8, 0(r5)
781; CHECK-NEXT:    lwa r9, 4(r5)
782; CHECK-NEXT:    lwa r10, 8(r5)
783; CHECK-NEXT:    addi r5, r5, 1
784; CHECK-NEXT:    mulld r7, r8, r7
785; CHECK-NEXT:    mulld r7, r7, r9
786; CHECK-NEXT:    maddld r3, r7, r10, r3
787; CHECK-NEXT:    bdnz .LBB9_2
788
789  %3 = sext i32 %1 to i64
790  %4 = icmp sgt i32 %1, 0
791  br i1 %4, label %5, label %31
792
7935:                                                ; preds = %2, %5
794  %6 = phi i64 [ %29, %5 ], [ 0, %2 ]
795  %7 = phi i64 [ %28, %5 ], [ 0, %2 ]
796  %8 = getelementptr inbounds i8, i8* %0, i64 %6
797  %9 = getelementptr inbounds i8, i8* %8, i64 1
798  %10 = bitcast i8* %9 to i32*
799  %11 = load i32, i32* %10, align 4
800  %12 = sext i32 %11 to i64
801  %13 = getelementptr inbounds i8, i8* %8, i64 2
802  %14 = bitcast i8* %13 to i32*
803  %15 = load i32, i32* %14, align 4
804  %16 = sext i32 %15 to i64
805  %17 = getelementptr inbounds i8, i8* %8, i64 6
806  %18 = bitcast i8* %17 to i32*
807  %19 = load i32, i32* %18, align 4
808  %20 = sext i32 %19 to i64
809  %21 = getelementptr inbounds i8, i8* %8, i64 10
810  %22 = bitcast i8* %21 to i32*
811  %23 = load i32, i32* %22, align 4
812  %24 = sext i32 %23 to i64
813  %25 = mul nsw i64 %16, %12
814  %26 = mul nsw i64 %25, %20
815  %27 = mul nsw i64 %26, %24
816  %28 = add nsw i64 %27, %7
817  %29 = add nuw nsw i64 %6, 1
818  %30 = icmp eq i64 %29, %3
819  br i1 %30, label %31, label %5
820
82131:                                               ; preds = %5, %2
822  %32 = phi i64 [ 0, %2 ], [ %28, %5 ]
823  %33 = add nsw i64 %32, %3
824  ret i64 %33
825}
826
827