xref: /llvm-project/llvm/test/CodeGen/SystemZ/fp-strict-mul-06.ll (revision a1710eb3cd5823c5d14899112ca3086acbdbe9cb)
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
5
6declare float @llvm.experimental.constrained.fma.f32(float, float, float, metadata, metadata)
7
8define float @f1(float %f1, float %f2, float %acc) #0 {
9; CHECK-LABEL: f1:
10; CHECK-SCALAR: maebr %f4, %f0, %f2
11; CHECK-SCALAR: ler %f0, %f4
12; CHECK-VECTOR: wfmasb %f0, %f0, %f2, %f4
13; CHECK: br %r14
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
18  ret float %res
19}
20
21define float @f2(float %f1, ptr %ptr, float %acc) #0 {
22; CHECK-LABEL: f2:
23; CHECK: maeb %f2, %f0, 0(%r2)
24; CHECK-SCALAR: ler %f0, %f2
25; CHECK-VECTOR: ldr %f0, %f2
26; CHECK: br %r14
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
32  ret float %res
33}
34
35define float @f3(float %f1, ptr %base, float %acc) #0 {
36; CHECK-LABEL: f3:
37; CHECK: maeb %f2, %f0, 4092(%r2)
38; CHECK-SCALAR: ler %f0, %f2
39; CHECK-VECTOR: ldr %f0, %f2
40; CHECK: br %r14
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
47  ret float %res
48}
49
50define 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.
53;
54; CHECK-LABEL: f4:
55; CHECK: aghi %r2, 4096
56; CHECK: maeb %f2, %f0, 0(%r2)
57; CHECK-SCALAR: ler %f0, %f2
58; CHECK-VECTOR: ldr %f0, %f2
59; CHECK: br %r14
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
66  ret float %res
67}
68
69define 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.
72;
73; CHECK-LABEL: f5:
74; CHECK: aghi %r2, -4
75; CHECK: maeb %f2, %f0, 0(%r2)
76; CHECK-SCALAR: ler %f0, %f2
77; CHECK-VECTOR: ldr %f0, %f2
78; CHECK: br %r14
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
85  ret float %res
86}
87
88define float @f6(float %f1, ptr %base, i64 %index, float %acc) #0 {
89; CHECK-LABEL: f6:
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
94; CHECK: br %r14
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
101  ret float %res
102}
103
104define float @f7(float %f1, ptr %base, i64 %index, float %acc) #0 {
105; CHECK-LABEL: f7:
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
110; CHECK: br %r14
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
118  ret float %res
119}
120
121define float @f8(float %f1, ptr %base, i64 %index, float %acc) #0 {
122; CHECK-LABEL: f8:
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
128; CHECK: br %r14
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
136  ret float %res
137}
138
139attributes #0 = { strictfp }
140