[ARM] More MVE compare vector splat combines for ANDs
[llvm-complete.git] / test / CodeGen / SystemZ / fp-strict-mul-02.ll
blob6f080f6e4ff8e0f4d929d16180741e705da6aedf
1 ; Test strict multiplication of two f32s, producing an f64 result.
2 ; FIXME: we do not have a strict version of fpext yet
4 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
6 declare float @foo()
7 declare double @llvm.experimental.constrained.fmul.f64(double, double, metadata, metadata)
9 ; Check register multiplication.
10 define double @f1(float %f1, float %f2) {
11 ; CHECK-LABEL: f1:
12 ; CHECK: mdebr %f0, %f2
13 ; CHECK: br %r14
14   %f1x = fpext float %f1 to double
15   %f2x = fpext float %f2 to double
16   %res = call double @llvm.experimental.constrained.fmul.f64(
17                         double %f1x, double %f2x,
18                         metadata !"round.dynamic",
19                         metadata !"fpexcept.strict")
20   ret double %res
23 ; Check the low end of the MDEB range.
24 define double @f2(float %f1, float *%ptr) {
25 ; CHECK-LABEL: f2:
26 ; CHECK: mdeb %f0, 0(%r2)
27 ; CHECK: br %r14
28   %f2 = load float, float *%ptr
29   %f1x = fpext float %f1 to double
30   %f2x = fpext float %f2 to double
31   %res = call double @llvm.experimental.constrained.fmul.f64(
32                         double %f1x, double %f2x,
33                         metadata !"round.dynamic",
34                         metadata !"fpexcept.strict")
35   ret double %res
38 ; Check the high end of the aligned MDEB range.
39 define double @f3(float %f1, float *%base) {
40 ; CHECK-LABEL: f3:
41 ; CHECK: mdeb %f0, 4092(%r2)
42 ; CHECK: br %r14
43   %ptr = getelementptr float, float *%base, i64 1023
44   %f2 = load float, float *%ptr
45   %f1x = fpext float %f1 to double
46   %f2x = fpext float %f2 to double
47   %res = call double @llvm.experimental.constrained.fmul.f64(
48                         double %f1x, double %f2x,
49                         metadata !"round.dynamic",
50                         metadata !"fpexcept.strict")
51   ret double %res
54 ; Check the next word up, which needs separate address logic.
55 ; Other sequences besides this one would be OK.
56 define double @f4(float %f1, float *%base) {
57 ; CHECK-LABEL: f4:
58 ; CHECK: aghi %r2, 4096
59 ; CHECK: mdeb %f0, 0(%r2)
60 ; CHECK: br %r14
61   %ptr = getelementptr float, float *%base, i64 1024
62   %f2 = load float, float *%ptr
63   %f1x = fpext float %f1 to double
64   %f2x = fpext float %f2 to double
65   %res = call double @llvm.experimental.constrained.fmul.f64(
66                         double %f1x, double %f2x,
67                         metadata !"round.dynamic",
68                         metadata !"fpexcept.strict")
69   ret double %res
72 ; Check negative displacements, which also need separate address logic.
73 define double @f5(float %f1, float *%base) {
74 ; CHECK-LABEL: f5:
75 ; CHECK: aghi %r2, -4
76 ; CHECK: mdeb %f0, 0(%r2)
77 ; CHECK: br %r14
78   %ptr = getelementptr float, float *%base, i64 -1
79   %f2 = load float, float *%ptr
80   %f1x = fpext float %f1 to double
81   %f2x = fpext float %f2 to double
82   %res = call double @llvm.experimental.constrained.fmul.f64(
83                         double %f1x, double %f2x,
84                         metadata !"round.dynamic",
85                         metadata !"fpexcept.strict")
86   ret double %res
89 ; Check that MDEB allows indices.
90 define double @f6(float %f1, float *%base, i64 %index) {
91 ; CHECK-LABEL: f6:
92 ; CHECK: sllg %r1, %r3, 2
93 ; CHECK: mdeb %f0, 400(%r1,%r2)
94 ; CHECK: br %r14
95   %ptr1 = getelementptr float, float *%base, i64 %index
96   %ptr2 = getelementptr float, float *%ptr1, i64 100
97   %f2 = load float, float *%ptr2
98   %f1x = fpext float %f1 to double
99   %f2x = fpext float %f2 to double
100   %res = call double @llvm.experimental.constrained.fmul.f64(
101                         double %f1x, double %f2x,
102                         metadata !"round.dynamic",
103                         metadata !"fpexcept.strict")
104   ret double %res
107 ; Check that multiplications of spilled values can use MDEB rather than MDEBR.
108 define float @f7(float *%ptr0) {
109 ; CHECK-LABEL: f7:
110 ; CHECK: brasl %r14, foo@PLT
111 ; CHECK: mdeb %f0, 16{{[04]}}(%r15)
112 ; CHECK: br %r14
113   %ptr1 = getelementptr float, float *%ptr0, i64 2
114   %ptr2 = getelementptr float, float *%ptr0, i64 4
115   %ptr3 = getelementptr float, float *%ptr0, i64 6
116   %ptr4 = getelementptr float, float *%ptr0, i64 8
117   %ptr5 = getelementptr float, float *%ptr0, i64 10
118   %ptr6 = getelementptr float, float *%ptr0, i64 12
119   %ptr7 = getelementptr float, float *%ptr0, i64 14
120   %ptr8 = getelementptr float, float *%ptr0, i64 16
121   %ptr9 = getelementptr float, float *%ptr0, i64 18
122   %ptr10 = getelementptr float, float *%ptr0, i64 20
124   %val0 = load float, float *%ptr0
125   %val1 = load float, float *%ptr1
126   %val2 = load float, float *%ptr2
127   %val3 = load float, float *%ptr3
128   %val4 = load float, float *%ptr4
129   %val5 = load float, float *%ptr5
130   %val6 = load float, float *%ptr6
131   %val7 = load float, float *%ptr7
132   %val8 = load float, float *%ptr8
133   %val9 = load float, float *%ptr9
134   %val10 = load float, float *%ptr10
136   %frob0 = fadd float %val0, %val0
137   %frob1 = fadd float %val1, %val1
138   %frob2 = fadd float %val2, %val2
139   %frob3 = fadd float %val3, %val3
140   %frob4 = fadd float %val4, %val4
141   %frob5 = fadd float %val5, %val5
142   %frob6 = fadd float %val6, %val6
143   %frob7 = fadd float %val7, %val7
144   %frob8 = fadd float %val8, %val8
145   %frob9 = fadd float %val9, %val9
146   %frob10 = fadd float %val9, %val10
148   store float %frob0, float *%ptr0
149   store float %frob1, float *%ptr1
150   store float %frob2, float *%ptr2
151   store float %frob3, float *%ptr3
152   store float %frob4, float *%ptr4
153   store float %frob5, float *%ptr5
154   store float %frob6, float *%ptr6
155   store float %frob7, float *%ptr7
156   store float %frob8, float *%ptr8
157   store float %frob9, float *%ptr9
158   store float %frob10, float *%ptr10
160   %ret = call float @foo()
162   %accext0 = fpext float %ret to double
163   %ext0 = fpext float %frob0 to double
164   %mul0 = call double @llvm.experimental.constrained.fmul.f64(
165                         double %accext0, double %ext0,
166                         metadata !"round.dynamic",
167                         metadata !"fpexcept.strict")
168   %extra0 = call double @llvm.experimental.constrained.fmul.f64(
169                         double %mul0, double 1.01,
170                         metadata !"round.dynamic",
171                         metadata !"fpexcept.strict")
172   %trunc0 = fptrunc double %extra0 to float
174   %accext1 = fpext float %trunc0 to double
175   %ext1 = fpext float %frob1 to double
176   %mul1 = call double @llvm.experimental.constrained.fmul.f64(
177                         double %accext1, double %ext1,
178                         metadata !"round.dynamic",
179                         metadata !"fpexcept.strict")
180   %extra1 = call double @llvm.experimental.constrained.fmul.f64(
181                         double %mul1, double 1.11,
182                         metadata !"round.dynamic",
183                         metadata !"fpexcept.strict")
184   %trunc1 = fptrunc double %extra1 to float
186   %accext2 = fpext float %trunc1 to double
187   %ext2 = fpext float %frob2 to double
188   %mul2 = call double @llvm.experimental.constrained.fmul.f64(
189                         double %accext2, double %ext2,
190                         metadata !"round.dynamic",
191                         metadata !"fpexcept.strict")
192   %extra2 = call double @llvm.experimental.constrained.fmul.f64(
193                         double %mul2, double 1.21,
194                         metadata !"round.dynamic",
195                         metadata !"fpexcept.strict")
196   %trunc2 = fptrunc double %extra2 to float
198   %accext3 = fpext float %trunc2 to double
199   %ext3 = fpext float %frob3 to double
200   %mul3 = call double @llvm.experimental.constrained.fmul.f64(
201                         double %accext3, double %ext3,
202                         metadata !"round.dynamic",
203                         metadata !"fpexcept.strict")
204   %extra3 = call double @llvm.experimental.constrained.fmul.f64(
205                         double %mul3, double 1.31,
206                         metadata !"round.dynamic",
207                         metadata !"fpexcept.strict")
208   %trunc3 = fptrunc double %extra3 to float
210   %accext4 = fpext float %trunc3 to double
211   %ext4 = fpext float %frob4 to double
212   %mul4 = call double @llvm.experimental.constrained.fmul.f64(
213                         double %accext4, double %ext4,
214                         metadata !"round.dynamic",
215                         metadata !"fpexcept.strict")
216   %extra4 = call double @llvm.experimental.constrained.fmul.f64(
217                         double %mul4, double 1.41,
218                         metadata !"round.dynamic",
219                         metadata !"fpexcept.strict")
220   %trunc4 = fptrunc double %extra4 to float
222   %accext5 = fpext float %trunc4 to double
223   %ext5 = fpext float %frob5 to double
224   %mul5 = call double @llvm.experimental.constrained.fmul.f64(
225                         double %accext5, double %ext5,
226                         metadata !"round.dynamic",
227                         metadata !"fpexcept.strict")
228   %extra5 = call double @llvm.experimental.constrained.fmul.f64(
229                         double %mul5, double 1.51,
230                         metadata !"round.dynamic",
231                         metadata !"fpexcept.strict")
232   %trunc5 = fptrunc double %extra5 to float
234   %accext6 = fpext float %trunc5 to double
235   %ext6 = fpext float %frob6 to double
236   %mul6 = call double @llvm.experimental.constrained.fmul.f64(
237                         double %accext6, double %ext6,
238                         metadata !"round.dynamic",
239                         metadata !"fpexcept.strict")
240   %extra6 = call double @llvm.experimental.constrained.fmul.f64(
241                         double %mul6, double 1.61,
242                         metadata !"round.dynamic",
243                         metadata !"fpexcept.strict")
244   %trunc6 = fptrunc double %extra6 to float
246   %accext7 = fpext float %trunc6 to double
247   %ext7 = fpext float %frob7 to double
248   %mul7 = call double @llvm.experimental.constrained.fmul.f64(
249                         double %accext7, double %ext7,
250                         metadata !"round.dynamic",
251                         metadata !"fpexcept.strict")
252   %extra7 = call double @llvm.experimental.constrained.fmul.f64(
253                         double %mul7, double 1.71,
254                         metadata !"round.dynamic",
255                         metadata !"fpexcept.strict")
256   %trunc7 = fptrunc double %extra7 to float
258   %accext8 = fpext float %trunc7 to double
259   %ext8 = fpext float %frob8 to double
260   %mul8 = call double @llvm.experimental.constrained.fmul.f64(
261                         double %accext8, double %ext8,
262                         metadata !"round.dynamic",
263                         metadata !"fpexcept.strict")
264   %extra8 = call double @llvm.experimental.constrained.fmul.f64(
265                         double %mul8, double 1.81,
266                         metadata !"round.dynamic",
267                         metadata !"fpexcept.strict")
268   %trunc8 = fptrunc double %extra8 to float
270   %accext9 = fpext float %trunc8 to double
271   %ext9 = fpext float %frob9 to double
272   %mul9 = call double @llvm.experimental.constrained.fmul.f64(
273                         double %accext9, double %ext9,
274                         metadata !"round.dynamic",
275                         metadata !"fpexcept.strict")
276   %extra9 = call double @llvm.experimental.constrained.fmul.f64(
277                         double %mul9, double 1.91,
278                         metadata !"round.dynamic",
279                         metadata !"fpexcept.strict")
280   %trunc9 = fptrunc double %extra9 to float
282   ret float %trunc9