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.experimental.constrained.fma.f32(float, float, float, metadata, metadata)
8 define float @f1(float %f1, float %f2, float %acc) #0 {
10 ; CHECK-SCALAR: maebr %f4, %f0, %f2
11 ; CHECK-SCALAR: ler %f0, %f4
12 ; CHECK-VECTOR: wfmasb %f0, %f0, %f2, %f4
14 %res = call float @llvm.experimental.constrained.fma.f32 (
15 float %f1, float %f2, float %acc,
16 metadata !"round.dynamic",
17 metadata !"fpexcept.strict") #0
21 define float @f2(float %f1, ptr %ptr, float %acc) #0 {
23 ; CHECK: maeb %f2, %f0, 0(%r2)
24 ; CHECK-SCALAR: ler %f0, %f2
25 ; CHECK-VECTOR: ldr %f0, %f2
27 %f2 = load float, ptr %ptr
28 %res = call float @llvm.experimental.constrained.fma.f32 (
29 float %f1, float %f2, float %acc,
30 metadata !"round.dynamic",
31 metadata !"fpexcept.strict") #0
35 define float @f3(float %f1, ptr %base, float %acc) #0 {
37 ; CHECK: maeb %f2, %f0, 4092(%r2)
38 ; CHECK-SCALAR: ler %f0, %f2
39 ; CHECK-VECTOR: ldr %f0, %f2
41 %ptr = getelementptr float, ptr %base, i64 1023
42 %f2 = load float, ptr %ptr
43 %res = call float @llvm.experimental.constrained.fma.f32 (
44 float %f1, float %f2, float %acc,
45 metadata !"round.dynamic",
46 metadata !"fpexcept.strict") #0
50 define float @f4(float %f1, ptr %base, float %acc) #0 {
51 ; The important thing here is that we don't generate an out-of-range
52 ; displacement. Other sequences besides this one would be OK.
55 ; CHECK: aghi %r2, 4096
56 ; CHECK: maeb %f2, %f0, 0(%r2)
57 ; CHECK-SCALAR: ler %f0, %f2
58 ; CHECK-VECTOR: ldr %f0, %f2
60 %ptr = getelementptr float, ptr %base, i64 1024
61 %f2 = load float, ptr %ptr
62 %res = call float @llvm.experimental.constrained.fma.f32 (
63 float %f1, float %f2, float %acc,
64 metadata !"round.dynamic",
65 metadata !"fpexcept.strict") #0
69 define float @f5(float %f1, ptr %base, float %acc) #0 {
70 ; Here too the important thing is that we don't generate an out-of-range
71 ; displacement. Other sequences besides this one would be OK.
75 ; CHECK: maeb %f2, %f0, 0(%r2)
76 ; CHECK-SCALAR: ler %f0, %f2
77 ; CHECK-VECTOR: ldr %f0, %f2
79 %ptr = getelementptr float, ptr %base, i64 -1
80 %f2 = load float, ptr %ptr
81 %res = call float @llvm.experimental.constrained.fma.f32 (
82 float %f1, float %f2, float %acc,
83 metadata !"round.dynamic",
84 metadata !"fpexcept.strict") #0
88 define float @f6(float %f1, ptr %base, i64 %index, float %acc) #0 {
90 ; CHECK: sllg %r1, %r3, 2
91 ; CHECK: maeb %f2, %f0, 0(%r1,%r2)
92 ; CHECK-SCALAR: ler %f0, %f2
93 ; CHECK-VECTOR: ldr %f0, %f2
95 %ptr = getelementptr float, ptr %base, i64 %index
96 %f2 = load float, ptr %ptr
97 %res = call float @llvm.experimental.constrained.fma.f32 (
98 float %f1, float %f2, float %acc,
99 metadata !"round.dynamic",
100 metadata !"fpexcept.strict") #0
104 define float @f7(float %f1, ptr %base, i64 %index, float %acc) #0 {
106 ; CHECK: sllg %r1, %r3, 2
107 ; CHECK: maeb %f2, %f0, 4092({{%r1,%r2|%r2,%r1}})
108 ; CHECK-SCALAR: ler %f0, %f2
109 ; CHECK-VECTOR: ldr %f0, %f2
111 %index2 = add i64 %index, 1023
112 %ptr = getelementptr float, ptr %base, i64 %index2
113 %f2 = load float, ptr %ptr
114 %res = call float @llvm.experimental.constrained.fma.f32 (
115 float %f1, float %f2, float %acc,
116 metadata !"round.dynamic",
117 metadata !"fpexcept.strict") #0
121 define float @f8(float %f1, ptr %base, i64 %index, float %acc) #0 {
123 ; CHECK: sllg %r1, %r3, 2
124 ; CHECK: lay %r1, 4096({{%r1,%r2|%r2,%r1}})
125 ; CHECK: maeb %f2, %f0, 0(%r1)
126 ; CHECK-SCALAR: ler %f0, %f2
127 ; CHECK-VECTOR: ldr %f0, %f2
129 %index2 = add i64 %index, 1024
130 %ptr = getelementptr float, ptr %base, i64 %index2
131 %f2 = load float, ptr %ptr
132 %res = call float @llvm.experimental.constrained.fma.f32 (
133 float %f1, float %f2, float %acc,
134 metadata !"round.dynamic",
135 metadata !"fpexcept.strict") #0
139 attributes #0 = { strictfp }