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=z14 \
4 ; RUN: | FileCheck -check-prefix=CHECK -check-prefix=CHECK-VECTOR %s
6 declare float @llvm.fma.f32(float %f1, float %f2, float %f3)
8 define float @f1(float %f1, float %f2, float %acc) {
10 ; CHECK-SCALAR: msebr %f4, %f0, %f2
11 ; CHECK-SCALAR: ler %f0, %f4
12 ; CHECK-VECTOR: wfmssb %f0, %f0, %f2, %f4
14 %negacc = fneg float %acc
15 %res = call float @llvm.fma.f32 (float %f1, float %f2, float %negacc)
19 define float @f2(float %f1, ptr %ptr, float %acc) {
21 ; CHECK: mseb %f2, %f0, 0(%r2)
22 ; CHECK-SCALAR: ler %f0, %f2
23 ; CHECK-VECTOR: ldr %f0, %f2
25 %f2 = load float, ptr %ptr
26 %negacc = fneg float %acc
27 %res = call float @llvm.fma.f32 (float %f1, float %f2, float %negacc)
31 define float @f3(float %f1, ptr %base, float %acc) {
33 ; CHECK: mseb %f2, %f0, 4092(%r2)
34 ; CHECK-SCALAR: ler %f0, %f2
35 ; CHECK-VECTOR: ldr %f0, %f2
37 %ptr = getelementptr float, ptr %base, i64 1023
38 %f2 = load float, ptr %ptr
39 %negacc = fneg float %acc
40 %res = call float @llvm.fma.f32 (float %f1, float %f2, float %negacc)
44 define float @f4(float %f1, ptr %base, float %acc) {
45 ; The important thing here is that we don't generate an out-of-range
46 ; displacement. Other sequences besides this one would be OK.
49 ; CHECK: aghi %r2, 4096
50 ; CHECK: mseb %f2, %f0, 0(%r2)
51 ; CHECK-SCALAR: ler %f0, %f2
52 ; CHECK-VECTOR: ldr %f0, %f2
54 %ptr = getelementptr float, ptr %base, i64 1024
55 %f2 = load float, ptr %ptr
56 %negacc = fneg float %acc
57 %res = call float @llvm.fma.f32 (float %f1, float %f2, float %negacc)
61 define float @f5(float %f1, ptr %base, float %acc) {
62 ; Here too the important thing is that we don't generate an out-of-range
63 ; displacement. Other sequences besides this one would be OK.
67 ; CHECK: mseb %f2, %f0, 0(%r2)
68 ; CHECK-SCALAR: ler %f0, %f2
69 ; CHECK-VECTOR: ldr %f0, %f2
71 %ptr = getelementptr float, ptr %base, i64 -1
72 %f2 = load float, ptr %ptr
73 %negacc = fneg float %acc
74 %res = call float @llvm.fma.f32 (float %f1, float %f2, float %negacc)
78 define float @f6(float %f1, ptr %base, i64 %index, float %acc) {
80 ; CHECK: sllg %r1, %r3, 2
81 ; CHECK: mseb %f2, %f0, 0(%r1,%r2)
82 ; CHECK-SCALAR: ler %f0, %f2
83 ; CHECK-VECTOR: ldr %f0, %f2
85 %ptr = getelementptr float, ptr %base, i64 %index
86 %f2 = load float, ptr %ptr
87 %negacc = fneg float %acc
88 %res = call float @llvm.fma.f32 (float %f1, float %f2, float %negacc)
92 define float @f7(float %f1, ptr %base, i64 %index, float %acc) {
94 ; CHECK: sllg %r1, %r3, 2
95 ; CHECK: mseb %f2, %f0, 4092({{%r1,%r2|%r2,%r1}})
96 ; CHECK-SCALAR: ler %f0, %f2
97 ; CHECK-VECTOR: ldr %f0, %f2
99 %index2 = add i64 %index, 1023
100 %ptr = getelementptr float, ptr %base, i64 %index2
101 %f2 = load float, ptr %ptr
102 %negacc = fneg float %acc
103 %res = call float @llvm.fma.f32 (float %f1, float %f2, float %negacc)
107 define float @f8(float %f1, ptr %base, i64 %index, float %acc) {
109 ; CHECK: sllg %r1, %r3, 2
110 ; CHECK: lay %r1, 4096({{%r1,%r2|%r2,%r1}})
111 ; CHECK: mseb %f2, %f0, 0(%r1)
112 ; CHECK-SCALAR: ler %f0, %f2
113 ; CHECK-VECTOR: ldr %f0, %f2
115 %index2 = add i64 %index, 1024
116 %ptr = getelementptr float, ptr %base, i64 %index2
117 %f2 = load float, ptr %ptr
118 %negacc = fneg float %acc
119 %res = call float @llvm.fma.f32 (float %f1, float %f2, float %negacc)