1; Test strict 32-bit square root.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 \
4; RUN:   | FileCheck -check-prefix=CHECK -check-prefix=CHECK-SCALAR %s
5; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
6
7declare float @llvm.experimental.constrained.sqrt.f32(float, metadata, metadata)
8
9; Check register square root.
10define float @f1(float %val) #0 {
11; CHECK-LABEL: f1:
12; CHECK: sqebr %f0, %f0
13; CHECK: br %r14
14  %res = call float @llvm.experimental.constrained.sqrt.f32(
15                        float %val,
16                        metadata !"round.dynamic",
17                        metadata !"fpexcept.strict") #0
18  ret float %res
19}
20
21; Check the low end of the SQEB range.
22define float @f2(float *%ptr) #0 {
23; CHECK-LABEL: f2:
24; CHECK: sqeb %f0, 0(%r2)
25; CHECK: br %r14
26  %val = load float, float *%ptr
27  %res = call float @llvm.experimental.constrained.sqrt.f32(
28                        float %val,
29                        metadata !"round.dynamic",
30                        metadata !"fpexcept.strict") #0
31  ret float %res
32}
33
34; Check the high end of the aligned SQEB range.
35define float @f3(float *%base) #0 {
36; CHECK-LABEL: f3:
37; CHECK: sqeb %f0, 4092(%r2)
38; CHECK: br %r14
39  %ptr = getelementptr float, float *%base, i64 1023
40  %val = load float, float *%ptr
41  %res = call float @llvm.experimental.constrained.sqrt.f32(
42                        float %val,
43                        metadata !"round.dynamic",
44                        metadata !"fpexcept.strict") #0
45  ret float %res
46}
47
48; Check the next word up, which needs separate address logic.
49; Other sequences besides this one would be OK.
50define float @f4(float *%base) #0 {
51; CHECK-LABEL: f4:
52; CHECK: aghi %r2, 4096
53; CHECK: sqeb %f0, 0(%r2)
54; CHECK: br %r14
55  %ptr = getelementptr float, float *%base, i64 1024
56  %val = load float, float *%ptr
57  %res = call float @llvm.experimental.constrained.sqrt.f32(
58                        float %val,
59                        metadata !"round.dynamic",
60                        metadata !"fpexcept.strict") #0
61  ret float %res
62}
63
64; Check negative displacements, which also need separate address logic.
65define float @f5(float *%base) #0 {
66; CHECK-LABEL: f5:
67; CHECK: aghi %r2, -4
68; CHECK: sqeb %f0, 0(%r2)
69; CHECK: br %r14
70  %ptr = getelementptr float, float *%base, i64 -1
71  %val = load float, float *%ptr
72  %res = call float @llvm.experimental.constrained.sqrt.f32(
73                        float %val,
74                        metadata !"round.dynamic",
75                        metadata !"fpexcept.strict") #0
76  ret float %res
77}
78
79; Check that SQEB allows indices.
80define float @f6(float *%base, i64 %index) #0 {
81; CHECK-LABEL: f6:
82; CHECK: sllg %r1, %r3, 2
83; CHECK: sqeb %f0, 400(%r1,%r2)
84; CHECK: br %r14
85  %ptr1 = getelementptr float, float *%base, i64 %index
86  %ptr2 = getelementptr float, float *%ptr1, i64 100
87  %val = load float, float *%ptr2
88  %res = call float @llvm.experimental.constrained.sqrt.f32(
89                        float %val,
90                        metadata !"round.dynamic",
91                        metadata !"fpexcept.strict") #0
92  ret float %res
93}
94
95attributes #0 = { strictfp }
96