1*f4a2713aSLionel Sambuc; Test 64-bit square root.
2*f4a2713aSLionel Sambuc;
3*f4a2713aSLionel Sambuc; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4*f4a2713aSLionel Sambuc
5*f4a2713aSLionel Sambucdeclare double @llvm.sqrt.f64(double %f)
6*f4a2713aSLionel Sambucdeclare double @sqrt(double)
7*f4a2713aSLionel Sambuc
8*f4a2713aSLionel Sambuc; Check register square root.
9*f4a2713aSLionel Sambucdefine double @f1(double %val) {
10*f4a2713aSLionel Sambuc; CHECK-LABEL: f1:
11*f4a2713aSLionel Sambuc; CHECK: sqdbr %f0, %f0
12*f4a2713aSLionel Sambuc; CHECK: br %r14
13*f4a2713aSLionel Sambuc  %res = call double @llvm.sqrt.f64(double %val)
14*f4a2713aSLionel Sambuc  ret double %res
15*f4a2713aSLionel Sambuc}
16*f4a2713aSLionel Sambuc
17*f4a2713aSLionel Sambuc; Check the low end of the SQDB range.
18*f4a2713aSLionel Sambucdefine double @f2(double *%ptr) {
19*f4a2713aSLionel Sambuc; CHECK-LABEL: f2:
20*f4a2713aSLionel Sambuc; CHECK: sqdb %f0, 0(%r2)
21*f4a2713aSLionel Sambuc; CHECK: br %r14
22*f4a2713aSLionel Sambuc  %val = load double *%ptr
23*f4a2713aSLionel Sambuc  %res = call double @llvm.sqrt.f64(double %val)
24*f4a2713aSLionel Sambuc  ret double %res
25*f4a2713aSLionel Sambuc}
26*f4a2713aSLionel Sambuc
27*f4a2713aSLionel Sambuc; Check the high end of the aligned SQDB range.
28*f4a2713aSLionel Sambucdefine double @f3(double *%base) {
29*f4a2713aSLionel Sambuc; CHECK-LABEL: f3:
30*f4a2713aSLionel Sambuc; CHECK: sqdb %f0, 4088(%r2)
31*f4a2713aSLionel Sambuc; CHECK: br %r14
32*f4a2713aSLionel Sambuc  %ptr = getelementptr double *%base, i64 511
33*f4a2713aSLionel Sambuc  %val = load double *%ptr
34*f4a2713aSLionel Sambuc  %res = call double @llvm.sqrt.f64(double %val)
35*f4a2713aSLionel Sambuc  ret double %res
36*f4a2713aSLionel Sambuc}
37*f4a2713aSLionel Sambuc
38*f4a2713aSLionel Sambuc; Check the next doubleword up, which needs separate address logic.
39*f4a2713aSLionel Sambuc; Other sequences besides this one would be OK.
40*f4a2713aSLionel Sambucdefine double @f4(double *%base) {
41*f4a2713aSLionel Sambuc; CHECK-LABEL: f4:
42*f4a2713aSLionel Sambuc; CHECK: aghi %r2, 4096
43*f4a2713aSLionel Sambuc; CHECK: sqdb %f0, 0(%r2)
44*f4a2713aSLionel Sambuc; CHECK: br %r14
45*f4a2713aSLionel Sambuc  %ptr = getelementptr double *%base, i64 512
46*f4a2713aSLionel Sambuc  %val = load double *%ptr
47*f4a2713aSLionel Sambuc  %res = call double @llvm.sqrt.f64(double %val)
48*f4a2713aSLionel Sambuc  ret double %res
49*f4a2713aSLionel Sambuc}
50*f4a2713aSLionel Sambuc
51*f4a2713aSLionel Sambuc; Check negative displacements, which also need separate address logic.
52*f4a2713aSLionel Sambucdefine double @f5(double *%base) {
53*f4a2713aSLionel Sambuc; CHECK-LABEL: f5:
54*f4a2713aSLionel Sambuc; CHECK: aghi %r2, -8
55*f4a2713aSLionel Sambuc; CHECK: sqdb %f0, 0(%r2)
56*f4a2713aSLionel Sambuc; CHECK: br %r14
57*f4a2713aSLionel Sambuc  %ptr = getelementptr double *%base, i64 -1
58*f4a2713aSLionel Sambuc  %val = load double *%ptr
59*f4a2713aSLionel Sambuc  %res = call double @llvm.sqrt.f64(double %val)
60*f4a2713aSLionel Sambuc  ret double %res
61*f4a2713aSLionel Sambuc}
62*f4a2713aSLionel Sambuc
63*f4a2713aSLionel Sambuc; Check that SQDB allows indices.
64*f4a2713aSLionel Sambucdefine double @f6(double *%base, i64 %index) {
65*f4a2713aSLionel Sambuc; CHECK-LABEL: f6:
66*f4a2713aSLionel Sambuc; CHECK: sllg %r1, %r3, 3
67*f4a2713aSLionel Sambuc; CHECK: sqdb %f0, 800(%r1,%r2)
68*f4a2713aSLionel Sambuc; CHECK: br %r14
69*f4a2713aSLionel Sambuc  %ptr1 = getelementptr double *%base, i64 %index
70*f4a2713aSLionel Sambuc  %ptr2 = getelementptr double *%ptr1, i64 100
71*f4a2713aSLionel Sambuc  %val = load double *%ptr2
72*f4a2713aSLionel Sambuc  %res = call double @llvm.sqrt.f64(double %val)
73*f4a2713aSLionel Sambuc  ret double %res
74*f4a2713aSLionel Sambuc}
75*f4a2713aSLionel Sambuc
76*f4a2713aSLionel Sambuc; Test a case where we spill the source of at least one SQDBR.  We want
77*f4a2713aSLionel Sambuc; to use SQDB if possible.
78*f4a2713aSLionel Sambucdefine void @f7(double *%ptr) {
79*f4a2713aSLionel Sambuc; CHECK-LABEL: f7:
80*f4a2713aSLionel Sambuc; CHECK: sqdb {{%f[0-9]+}}, 160(%r15)
81*f4a2713aSLionel Sambuc; CHECK: br %r14
82*f4a2713aSLionel Sambuc  %val0 = load volatile double *%ptr
83*f4a2713aSLionel Sambuc  %val1 = load volatile double *%ptr
84*f4a2713aSLionel Sambuc  %val2 = load volatile double *%ptr
85*f4a2713aSLionel Sambuc  %val3 = load volatile double *%ptr
86*f4a2713aSLionel Sambuc  %val4 = load volatile double *%ptr
87*f4a2713aSLionel Sambuc  %val5 = load volatile double *%ptr
88*f4a2713aSLionel Sambuc  %val6 = load volatile double *%ptr
89*f4a2713aSLionel Sambuc  %val7 = load volatile double *%ptr
90*f4a2713aSLionel Sambuc  %val8 = load volatile double *%ptr
91*f4a2713aSLionel Sambuc  %val9 = load volatile double *%ptr
92*f4a2713aSLionel Sambuc  %val10 = load volatile double *%ptr
93*f4a2713aSLionel Sambuc  %val11 = load volatile double *%ptr
94*f4a2713aSLionel Sambuc  %val12 = load volatile double *%ptr
95*f4a2713aSLionel Sambuc  %val13 = load volatile double *%ptr
96*f4a2713aSLionel Sambuc  %val14 = load volatile double *%ptr
97*f4a2713aSLionel Sambuc  %val15 = load volatile double *%ptr
98*f4a2713aSLionel Sambuc  %val16 = load volatile double *%ptr
99*f4a2713aSLionel Sambuc
100*f4a2713aSLionel Sambuc  %sqrt0 = call double @llvm.sqrt.f64(double %val0)
101*f4a2713aSLionel Sambuc  %sqrt1 = call double @llvm.sqrt.f64(double %val1)
102*f4a2713aSLionel Sambuc  %sqrt2 = call double @llvm.sqrt.f64(double %val2)
103*f4a2713aSLionel Sambuc  %sqrt3 = call double @llvm.sqrt.f64(double %val3)
104*f4a2713aSLionel Sambuc  %sqrt4 = call double @llvm.sqrt.f64(double %val4)
105*f4a2713aSLionel Sambuc  %sqrt5 = call double @llvm.sqrt.f64(double %val5)
106*f4a2713aSLionel Sambuc  %sqrt6 = call double @llvm.sqrt.f64(double %val6)
107*f4a2713aSLionel Sambuc  %sqrt7 = call double @llvm.sqrt.f64(double %val7)
108*f4a2713aSLionel Sambuc  %sqrt8 = call double @llvm.sqrt.f64(double %val8)
109*f4a2713aSLionel Sambuc  %sqrt9 = call double @llvm.sqrt.f64(double %val9)
110*f4a2713aSLionel Sambuc  %sqrt10 = call double @llvm.sqrt.f64(double %val10)
111*f4a2713aSLionel Sambuc  %sqrt11 = call double @llvm.sqrt.f64(double %val11)
112*f4a2713aSLionel Sambuc  %sqrt12 = call double @llvm.sqrt.f64(double %val12)
113*f4a2713aSLionel Sambuc  %sqrt13 = call double @llvm.sqrt.f64(double %val13)
114*f4a2713aSLionel Sambuc  %sqrt14 = call double @llvm.sqrt.f64(double %val14)
115*f4a2713aSLionel Sambuc  %sqrt15 = call double @llvm.sqrt.f64(double %val15)
116*f4a2713aSLionel Sambuc  %sqrt16 = call double @llvm.sqrt.f64(double %val16)
117*f4a2713aSLionel Sambuc
118*f4a2713aSLionel Sambuc  store volatile double %val0, double *%ptr
119*f4a2713aSLionel Sambuc  store volatile double %val1, double *%ptr
120*f4a2713aSLionel Sambuc  store volatile double %val2, double *%ptr
121*f4a2713aSLionel Sambuc  store volatile double %val3, double *%ptr
122*f4a2713aSLionel Sambuc  store volatile double %val4, double *%ptr
123*f4a2713aSLionel Sambuc  store volatile double %val5, double *%ptr
124*f4a2713aSLionel Sambuc  store volatile double %val6, double *%ptr
125*f4a2713aSLionel Sambuc  store volatile double %val7, double *%ptr
126*f4a2713aSLionel Sambuc  store volatile double %val8, double *%ptr
127*f4a2713aSLionel Sambuc  store volatile double %val9, double *%ptr
128*f4a2713aSLionel Sambuc  store volatile double %val10, double *%ptr
129*f4a2713aSLionel Sambuc  store volatile double %val11, double *%ptr
130*f4a2713aSLionel Sambuc  store volatile double %val12, double *%ptr
131*f4a2713aSLionel Sambuc  store volatile double %val13, double *%ptr
132*f4a2713aSLionel Sambuc  store volatile double %val14, double *%ptr
133*f4a2713aSLionel Sambuc  store volatile double %val15, double *%ptr
134*f4a2713aSLionel Sambuc  store volatile double %val16, double *%ptr
135*f4a2713aSLionel Sambuc
136*f4a2713aSLionel Sambuc  store volatile double %sqrt0, double *%ptr
137*f4a2713aSLionel Sambuc  store volatile double %sqrt1, double *%ptr
138*f4a2713aSLionel Sambuc  store volatile double %sqrt2, double *%ptr
139*f4a2713aSLionel Sambuc  store volatile double %sqrt3, double *%ptr
140*f4a2713aSLionel Sambuc  store volatile double %sqrt4, double *%ptr
141*f4a2713aSLionel Sambuc  store volatile double %sqrt5, double *%ptr
142*f4a2713aSLionel Sambuc  store volatile double %sqrt6, double *%ptr
143*f4a2713aSLionel Sambuc  store volatile double %sqrt7, double *%ptr
144*f4a2713aSLionel Sambuc  store volatile double %sqrt8, double *%ptr
145*f4a2713aSLionel Sambuc  store volatile double %sqrt9, double *%ptr
146*f4a2713aSLionel Sambuc  store volatile double %sqrt10, double *%ptr
147*f4a2713aSLionel Sambuc  store volatile double %sqrt11, double *%ptr
148*f4a2713aSLionel Sambuc  store volatile double %sqrt12, double *%ptr
149*f4a2713aSLionel Sambuc  store volatile double %sqrt13, double *%ptr
150*f4a2713aSLionel Sambuc  store volatile double %sqrt14, double *%ptr
151*f4a2713aSLionel Sambuc  store volatile double %sqrt15, double *%ptr
152*f4a2713aSLionel Sambuc  store volatile double %sqrt16, double *%ptr
153*f4a2713aSLionel Sambuc
154*f4a2713aSLionel Sambuc  ret void
155*f4a2713aSLionel Sambuc}
156*f4a2713aSLionel Sambuc
157*f4a2713aSLionel Sambuc; Check that a call to the normal sqrt function is lowered.
158*f4a2713aSLionel Sambucdefine double @f8(double %dummy, double %val) {
159*f4a2713aSLionel Sambuc; CHECK-LABEL: f8:
160*f4a2713aSLionel Sambuc; CHECK: sqdbr %f0, %f2
161*f4a2713aSLionel Sambuc; CHECK: cdbr %f0, %f0
162*f4a2713aSLionel Sambuc; CHECK: jo [[LABEL:\.L.*]]
163*f4a2713aSLionel Sambuc; CHECK: br %r14
164*f4a2713aSLionel Sambuc; CHECK: [[LABEL]]:
165*f4a2713aSLionel Sambuc; CHECK: ldr %f0, %f2
166*f4a2713aSLionel Sambuc; CHECK: jg sqrt@PLT
167*f4a2713aSLionel Sambuc  %res = tail call double @sqrt(double %val)
168*f4a2713aSLionel Sambuc  ret double %res
169*f4a2713aSLionel Sambuc}
170