Don't form PPC CTR loops for over-sized exit counts
[oota-llvm.git] / test / CodeGen / SystemZ / fp-mul-04.ll
1 ; Test multiplication of two f64s, producing an f128 result.
2 ;
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4
5 ; Check register multiplication.  "mxdbr %f0, %f2" is not valid from LLVM's
6 ; point of view, because %f2 is the low register of the FP128 %f0.  Pass the
7 ; multiplier in %f4 instead.
8 define void @f1(double %f1, double %dummy, double %f2, fp128 *%dst) {
9 ; CHECK: f1:
10 ; CHECK: mxdbr %f0, %f4
11 ; CHECK: std %f0, 0(%r2)
12 ; CHECK: std %f2, 8(%r2)
13 ; CHECK: br %r14
14   %f1x = fpext double %f1 to fp128
15   %f2x = fpext double %f2 to fp128
16   %res = fmul fp128 %f1x, %f2x
17   store fp128 %res, fp128 *%dst
18   ret void
19 }
20
21 ; Check the low end of the MXDB range.
22 define void @f2(double %f1, double *%ptr, fp128 *%dst) {
23 ; CHECK: f2:
24 ; CHECK: mxdb %f0, 0(%r2)
25 ; CHECK: std %f0, 0(%r3)
26 ; CHECK: std %f2, 8(%r3)
27 ; CHECK: br %r14
28   %f2 = load double *%ptr
29   %f1x = fpext double %f1 to fp128
30   %f2x = fpext double %f2 to fp128
31   %res = fmul fp128 %f1x, %f2x
32   store fp128 %res, fp128 *%dst
33   ret void
34 }
35
36 ; Check the high end of the aligned MXDB range.
37 define void @f3(double %f1, double *%base, fp128 *%dst) {
38 ; CHECK: f3:
39 ; CHECK: mxdb %f0, 4088(%r2)
40 ; CHECK: std %f0, 0(%r3)
41 ; CHECK: std %f2, 8(%r3)
42 ; CHECK: br %r14
43   %ptr = getelementptr double *%base, i64 511
44   %f2 = load double *%ptr
45   %f1x = fpext double %f1 to fp128
46   %f2x = fpext double %f2 to fp128
47   %res = fmul fp128 %f1x, %f2x
48   store fp128 %res, fp128 *%dst
49   ret void
50 }
51
52 ; Check the next doubleword up, which needs separate address logic.
53 ; Other sequences besides this one would be OK.
54 define void @f4(double %f1, double *%base, fp128 *%dst) {
55 ; CHECK: f4:
56 ; CHECK: aghi %r2, 4096
57 ; CHECK: mxdb %f0, 0(%r2)
58 ; CHECK: std %f0, 0(%r3)
59 ; CHECK: std %f2, 8(%r3)
60 ; CHECK: br %r14
61   %ptr = getelementptr double *%base, i64 512
62   %f2 = load double *%ptr
63   %f1x = fpext double %f1 to fp128
64   %f2x = fpext double %f2 to fp128
65   %res = fmul fp128 %f1x, %f2x
66   store fp128 %res, fp128 *%dst
67   ret void
68 }
69
70 ; Check negative displacements, which also need separate address logic.
71 define void @f5(double %f1, double *%base, fp128 *%dst) {
72 ; CHECK: f5:
73 ; CHECK: aghi %r2, -8
74 ; CHECK: mxdb %f0, 0(%r2)
75 ; CHECK: std %f0, 0(%r3)
76 ; CHECK: std %f2, 8(%r3)
77 ; CHECK: br %r14
78   %ptr = getelementptr double *%base, i64 -1
79   %f2 = load double *%ptr
80   %f1x = fpext double %f1 to fp128
81   %f2x = fpext double %f2 to fp128
82   %res = fmul fp128 %f1x, %f2x
83   store fp128 %res, fp128 *%dst
84   ret void
85 }
86
87 ; Check that MXDB allows indices.
88 define void @f6(double %f1, double *%base, i64 %index, fp128 *%dst) {
89 ; CHECK: f6:
90 ; CHECK: sllg %r1, %r3, 3
91 ; CHECK: mxdb %f0, 800(%r1,%r2)
92 ; CHECK: std %f0, 0(%r4)
93 ; CHECK: std %f2, 8(%r4)
94 ; CHECK: br %r14
95   %ptr1 = getelementptr double *%base, i64 %index
96   %ptr2 = getelementptr double *%ptr1, i64 100
97   %f2 = load double *%ptr2
98   %f1x = fpext double %f1 to fp128
99   %f2x = fpext double %f2 to fp128
100   %res = fmul fp128 %f1x, %f2x
101   store fp128 %res, fp128 *%dst
102   ret void
103 }