1; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
2
3declare double @llvm.fma.f64(double %f1, double %f2, double %f3)
4
5define double @f1(double %f1, double %f2, double %acc) {
6; CHECK-LABEL: f1:
7; CHECK: madbr %f4, %f0, %f2
8; CHECK: ldr %f0, %f4
9; CHECK: br %r14
10  %res = call double @llvm.fma.f64 (double %f1, double %f2, double %acc)
11  ret double %res
12}
13
14define double @f2(double %f1, double *%ptr, double %acc) {
15; CHECK-LABEL: f2:
16; CHECK: madb %f2, %f0, 0(%r2)
17; CHECK: ldr %f0, %f2
18; CHECK: br %r14
19  %f2 = load double *%ptr
20  %res = call double @llvm.fma.f64 (double %f1, double %f2, double %acc)
21  ret double %res
22}
23
24define double @f3(double %f1, double *%base, double %acc) {
25; CHECK-LABEL: f3:
26; CHECK: madb %f2, %f0, 4088(%r2)
27; CHECK: ldr %f0, %f2
28; CHECK: br %r14
29  %ptr = getelementptr double *%base, i64 511
30  %f2 = load double *%ptr
31  %res = call double @llvm.fma.f64 (double %f1, double %f2, double %acc)
32  ret double %res
33}
34
35define double @f4(double %f1, double *%base, double %acc) {
36; The important thing here is that we don't generate an out-of-range
37; displacement.  Other sequences besides this one would be OK.
38;
39; CHECK-LABEL: f4:
40; CHECK: aghi %r2, 4096
41; CHECK: madb %f2, %f0, 0(%r2)
42; CHECK: ldr %f0, %f2
43; CHECK: br %r14
44  %ptr = getelementptr double *%base, i64 512
45  %f2 = load double *%ptr
46  %res = call double @llvm.fma.f64 (double %f1, double %f2, double %acc)
47  ret double %res
48}
49
50define double @f5(double %f1, double *%base, double %acc) {
51; Here too the important thing is that we don't generate an out-of-range
52; displacement.  Other sequences besides this one would be OK.
53;
54; CHECK-LABEL: f5:
55; CHECK: aghi %r2, -8
56; CHECK: madb %f2, %f0, 0(%r2)
57; CHECK: ldr %f0, %f2
58; CHECK: br %r14
59  %ptr = getelementptr double *%base, i64 -1
60  %f2 = load double *%ptr
61  %res = call double @llvm.fma.f64 (double %f1, double %f2, double %acc)
62  ret double %res
63}
64
65define double @f6(double %f1, double *%base, i64 %index, double %acc) {
66; CHECK-LABEL: f6:
67; CHECK: sllg %r1, %r3, 3
68; CHECK: madb %f2, %f0, 0(%r1,%r2)
69; CHECK: ldr %f0, %f2
70; CHECK: br %r14
71  %ptr = getelementptr double *%base, i64 %index
72  %f2 = load double *%ptr
73  %res = call double @llvm.fma.f64 (double %f1, double %f2, double %acc)
74  ret double %res
75}
76
77define double @f7(double %f1, double *%base, i64 %index, double %acc) {
78; CHECK-LABEL: f7:
79; CHECK: sllg %r1, %r3, 3
80; CHECK: madb %f2, %f0, 4088({{%r1,%r2|%r2,%r1}})
81; CHECK: ldr %f0, %f2
82; CHECK: br %r14
83  %index2 = add i64 %index, 511
84  %ptr = getelementptr double *%base, i64 %index2
85  %f2 = load double *%ptr
86  %res = call double @llvm.fma.f64 (double %f1, double %f2, double %acc)
87  ret double %res
88}
89
90define double @f8(double %f1, double *%base, i64 %index, double %acc) {
91; CHECK-LABEL: f8:
92; CHECK: sllg %r1, %r3, 3
93; CHECK: lay %r1, 4096({{%r1,%r2|%r2,%r1}})
94; CHECK: madb %f2, %f0, 0(%r1)
95; CHECK: ldr %f0, %f2
96; CHECK: br %r14
97  %index2 = add i64 %index, 512
98  %ptr = getelementptr double *%base, i64 %index2
99  %f2 = load double *%ptr
100  %res = call double @llvm.fma.f64 (double %f1, double %f2, double %acc)
101  ret double %res
102}
103