1 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 \
2 ; RUN: | FileCheck -check-prefix=CHECK -check-prefix=CHECK-SCALAR %s
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 \
4 ; RUN: | FileCheck -check-prefix=CHECK -check-prefix=CHECK-VECTOR %s
6 declare double @llvm.experimental.constrained.fma.f64(double %f1, double %f2, double %f3, metadata, metadata)
8 define double @f1(double %f1, double %f2, double %acc) #0 {
10 ; CHECK-SCALAR: madbr %f4, %f0, %f2
11 ; CHECK-SCALAR: ldr %f0, %f4
12 ; CHECK-VECTOR: wfmadb %f0, %f0, %f2, %f4
14 %res = call double @llvm.experimental.constrained.fma.f64 (
15 double %f1, double %f2, double %acc,
16 metadata !"round.dynamic",
17 metadata !"fpexcept.strict") #0
21 define double @f2(double %f1, ptr %ptr, double %acc) #0 {
23 ; CHECK: madb %f2, %f0, 0(%r2)
26 %f2 = load double, ptr %ptr
27 %res = call double @llvm.experimental.constrained.fma.f64 (
28 double %f1, double %f2, double %acc,
29 metadata !"round.dynamic",
30 metadata !"fpexcept.strict") #0
34 define double @f3(double %f1, ptr %base, double %acc) #0 {
36 ; CHECK: madb %f2, %f0, 4088(%r2)
39 %ptr = getelementptr double, ptr %base, i64 511
40 %f2 = load double, ptr %ptr
41 %res = call double @llvm.experimental.constrained.fma.f64 (
42 double %f1, double %f2, double %acc,
43 metadata !"round.dynamic",
44 metadata !"fpexcept.strict") #0
48 define double @f4(double %f1, ptr %base, double %acc) #0 {
49 ; The important thing here is that we don't generate an out-of-range
50 ; displacement. Other sequences besides this one would be OK.
53 ; CHECK: aghi %r2, 4096
54 ; CHECK: madb %f2, %f0, 0(%r2)
57 %ptr = getelementptr double, ptr %base, i64 512
58 %f2 = load double, ptr %ptr
59 %res = call double @llvm.experimental.constrained.fma.f64 (
60 double %f1, double %f2, double %acc,
61 metadata !"round.dynamic",
62 metadata !"fpexcept.strict") #0
66 define double @f5(double %f1, ptr %base, double %acc) #0 {
67 ; Here too the important thing is that we don't generate an out-of-range
68 ; displacement. Other sequences besides this one would be OK.
72 ; CHECK: madb %f2, %f0, 0(%r2)
75 %ptr = getelementptr double, ptr %base, i64 -1
76 %f2 = load double, ptr %ptr
77 %res = call double @llvm.experimental.constrained.fma.f64 (
78 double %f1, double %f2, double %acc,
79 metadata !"round.dynamic",
80 metadata !"fpexcept.strict") #0
84 define double @f6(double %f1, ptr %base, i64 %index, double %acc) #0 {
86 ; CHECK: sllg %r1, %r3, 3
87 ; CHECK: madb %f2, %f0, 0(%r1,%r2)
90 %ptr = getelementptr double, ptr %base, i64 %index
91 %f2 = load double, ptr %ptr
92 %res = call double @llvm.experimental.constrained.fma.f64 (
93 double %f1, double %f2, double %acc,
94 metadata !"round.dynamic",
95 metadata !"fpexcept.strict") #0
99 define double @f7(double %f1, ptr %base, i64 %index, double %acc) #0 {
101 ; CHECK: sllg %r1, %r3, 3
102 ; CHECK: madb %f2, %f0, 4088({{%r1,%r2|%r2,%r1}})
103 ; CHECK: ldr %f0, %f2
105 %index2 = add i64 %index, 511
106 %ptr = getelementptr double, ptr %base, i64 %index2
107 %f2 = load double, ptr %ptr
108 %res = call double @llvm.experimental.constrained.fma.f64 (
109 double %f1, double %f2, double %acc,
110 metadata !"round.dynamic",
111 metadata !"fpexcept.strict") #0
115 define double @f8(double %f1, ptr %base, i64 %index, double %acc) #0 {
117 ; CHECK: sllg %r1, %r3, 3
118 ; CHECK: lay %r1, 4096({{%r1,%r2|%r2,%r1}})
119 ; CHECK: madb %f2, %f0, 0(%r1)
120 ; CHECK: ldr %f0, %f2
122 %index2 = add i64 %index, 512
123 %ptr = getelementptr double, ptr %base, i64 %index2
124 %f2 = load double, ptr %ptr
125 %res = call double @llvm.experimental.constrained.fma.f64 (
126 double %f1, double %f2, double %acc,
127 metadata !"round.dynamic",
128 metadata !"fpexcept.strict") #0
132 attributes #0 = { strictfp }