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