[X86] combineTargetShuffle - commute VPERMV3 shuffles so any load is on the RHS
[llvm-project.git] / llvm / test / CodeGen / SystemZ / fp-strict-alias.ll
blob32d05b7ebb160d07edf108f66040502ff56a2754
1 ; Verify that strict FP operations are not rescheduled
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s
5 declare float @llvm.experimental.constrained.sqrt.f32(float, metadata, metadata)
6 declare float @llvm.sqrt.f32(float)
7 declare void @llvm.s390.sfpc(i32)
8 declare void @bar()
10 ; The basic assumption of all following tests is that on z13, we never
11 ; want to see two square root instructions directly in a row, so the
12 ; post-RA scheduler will always schedule something else in between
13 ; whenever possible.
15 ; We can move any FP operation across a (normal) store.
17 define void @f1(float %f1, float %f2, ptr %ptr1, ptr %ptr2) {
18 ; CHECK-LABEL: f1:
19 ; CHECK: sqebr
20 ; CHECK: ste
21 ; CHECK: sqebr
22 ; CHECK: ste
23 ; CHECK: br %r14
25   %sqrt1 = call float @llvm.sqrt.f32(float %f1)
26   %sqrt2 = call float @llvm.sqrt.f32(float %f2)
28   store float %sqrt1, ptr %ptr1
29   store float %sqrt2, ptr %ptr2
31   ret void
34 define void @f2(float %f1, float %f2, ptr %ptr1, ptr %ptr2) #0 {
35 ; CHECK-LABEL: f2:
36 ; CHECK: sqebr
37 ; CHECK: ste
38 ; CHECK: sqebr
39 ; CHECK: ste
40 ; CHECK: br %r14
42   %sqrt1 = call float @llvm.experimental.constrained.sqrt.f32(
43                         float %f1,
44                         metadata !"round.dynamic",
45                         metadata !"fpexcept.ignore") #0
46   %sqrt2 = call float @llvm.experimental.constrained.sqrt.f32(
47                         float %f2,
48                         metadata !"round.dynamic",
49                         metadata !"fpexcept.ignore") #0
51   store float %sqrt1, ptr %ptr1
52   store float %sqrt2, ptr %ptr2
54   ret void
57 define void @f3(float %f1, float %f2, ptr %ptr1, ptr %ptr2) #0 {
58 ; CHECK-LABEL: f3:
59 ; CHECK: sqebr
60 ; CHECK: ste
61 ; CHECK: sqebr
62 ; CHECK: ste
63 ; CHECK: br %r14
65   %sqrt1 = call float @llvm.experimental.constrained.sqrt.f32(
66                         float %f1,
67                         metadata !"round.dynamic",
68                         metadata !"fpexcept.maytrap") #0
69   %sqrt2 = call float @llvm.experimental.constrained.sqrt.f32(
70                         float %f2,
71                         metadata !"round.dynamic",
72                         metadata !"fpexcept.maytrap") #0
74   store float %sqrt1, ptr %ptr1
75   store float %sqrt2, ptr %ptr2
77   ret void
80 define void @f4(float %f1, float %f2, ptr %ptr1, ptr %ptr2) #0 {
81 ; CHECK-LABEL: f4:
82 ; CHECK: sqebr
83 ; CHECK: ste
84 ; CHECK: sqebr
85 ; CHECK: ste
86 ; CHECK: br %r14
88   %sqrt1 = call float @llvm.experimental.constrained.sqrt.f32(
89                         float %f1,
90                         metadata !"round.dynamic",
91                         metadata !"fpexcept.strict") #0
92   %sqrt2 = call float @llvm.experimental.constrained.sqrt.f32(
93                         float %f2,
94                         metadata !"round.dynamic",
95                         metadata !"fpexcept.strict") #0
97   store float %sqrt1, ptr %ptr1
98   store float %sqrt2, ptr %ptr2
100   ret void
104 ; We can move a non-strict FP operation or a fpexcept.ignore
105 ; operation even across a volatile store, but not a fpexcept.maytrap
106 ; or fpexcept.strict operation.
108 define void @f5(float %f1, float %f2, ptr %ptr1, ptr %ptr2) {
109 ; CHECK-LABEL: f5:
110 ; CHECK: sqebr
111 ; CHECK: ste
112 ; CHECK: sqebr
113 ; CHECK: ste
114 ; CHECK: br %r14
116   %sqrt1 = call float @llvm.sqrt.f32(float %f1)
117   %sqrt2 = call float @llvm.sqrt.f32(float %f2)
119   store volatile float %sqrt1, ptr %ptr1
120   store volatile float %sqrt2, ptr %ptr2
122   ret void
125 define void @f6(float %f1, float %f2, ptr %ptr1, ptr %ptr2) #0 {
126 ; CHECK-LABEL: f6:
127 ; CHECK: sqebr
128 ; CHECK: ste
129 ; CHECK: sqebr
130 ; CHECK: ste
131 ; CHECK: br %r14
133   %sqrt1 = call float @llvm.experimental.constrained.sqrt.f32(
134                         float %f1,
135                         metadata !"round.dynamic",
136                         metadata !"fpexcept.ignore") #0
137   %sqrt2 = call float @llvm.experimental.constrained.sqrt.f32(
138                         float %f2,
139                         metadata !"round.dynamic",
140                         metadata !"fpexcept.ignore") #0
142   store volatile float %sqrt1, ptr %ptr1
143   store volatile float %sqrt2, ptr %ptr2
145   ret void
148 define void @f7(float %f1, float %f2, ptr %ptr1, ptr %ptr2) #0 {
149 ; CHECK-LABEL: f7:
150 ; CHECK: sqebr
151 ; CHECK: sqebr
152 ; CHECK: ste
153 ; CHECK: ste
154 ; CHECK: br %r14
156   %sqrt1 = call float @llvm.experimental.constrained.sqrt.f32(
157                         float %f1,
158                         metadata !"round.dynamic",
159                         metadata !"fpexcept.maytrap") #0
160   %sqrt2 = call float @llvm.experimental.constrained.sqrt.f32(
161                         float %f2,
162                         metadata !"round.dynamic",
163                         metadata !"fpexcept.maytrap") #0
165   store volatile float %sqrt1, ptr %ptr1
166   store volatile float %sqrt2, ptr %ptr2
168   ret void
171 define void @f8(float %f1, float %f2, ptr %ptr1, ptr %ptr2) #0 {
172 ; CHECK-LABEL: f8:
173 ; CHECK: sqebr
174 ; CHECK: sqebr
175 ; CHECK: ste
176 ; CHECK: ste
177 ; CHECK: br %r14
179   %sqrt1 = call float @llvm.experimental.constrained.sqrt.f32(
180                         float %f1,
181                         metadata !"round.dynamic",
182                         metadata !"fpexcept.strict") #0
183   %sqrt2 = call float @llvm.experimental.constrained.sqrt.f32(
184                         float %f2,
185                         metadata !"round.dynamic",
186                         metadata !"fpexcept.strict") #0
188   store volatile float %sqrt1, ptr %ptr1
189   store volatile float %sqrt2, ptr %ptr2
191   ret void
195 ; No variant of FP operations can be scheduled across a SPFC.
197 define void @f9(float %f1, float %f2, ptr %ptr1, ptr %ptr2) {
198 ; CHECK-LABEL: f9:
199 ; CHECK: sqebr
200 ; CHECK: sqebr
201 ; CHECK: ste
202 ; CHECK: ste
203 ; CHECK: br %r14
205   %sqrt1 = call float @llvm.sqrt.f32(float %f1)
206   %sqrt2 = call float @llvm.sqrt.f32(float %f2)
208   call void @llvm.s390.sfpc(i32 0)
210   store float %sqrt1, ptr %ptr1
211   store float %sqrt2, ptr %ptr2
213   ret void
216 define void @f10(float %f1, float %f2, ptr %ptr1, ptr %ptr2) #0 {
217 ; CHECK-LABEL: f10:
218 ; CHECK: sqebr
219 ; CHECK: sqebr
220 ; CHECK: ste
221 ; CHECK: ste
222 ; CHECK: br %r14
224   %sqrt1 = call float @llvm.experimental.constrained.sqrt.f32(
225                         float %f1,
226                         metadata !"round.dynamic",
227                         metadata !"fpexcept.ignore") #0
228   %sqrt2 = call float @llvm.experimental.constrained.sqrt.f32(
229                         float %f2,
230                         metadata !"round.dynamic",
231                         metadata !"fpexcept.ignore") #0
233   call void @llvm.s390.sfpc(i32 0) #0
235   store float %sqrt1, ptr %ptr1
236   store float %sqrt2, ptr %ptr2
238   ret void
241 define void @f11(float %f1, float %f2, ptr %ptr1, ptr %ptr2) #0 {
242 ; CHECK-LABEL: f11:
243 ; CHECK: sqebr
244 ; CHECK: sqebr
245 ; CHECK: ste
246 ; CHECK: ste
247 ; CHECK: br %r14
249   %sqrt1 = call float @llvm.experimental.constrained.sqrt.f32(
250                         float %f1,
251                         metadata !"round.dynamic",
252                         metadata !"fpexcept.maytrap") #0
253   %sqrt2 = call float @llvm.experimental.constrained.sqrt.f32(
254                         float %f2,
255                         metadata !"round.dynamic",
256                         metadata !"fpexcept.maytrap") #0
258   call void @llvm.s390.sfpc(i32 0) #0
260   store float %sqrt1, ptr %ptr1
261   store float %sqrt2, ptr %ptr2
263   ret void
266 define void @f12(float %f1, float %f2, ptr %ptr1, ptr %ptr2) #0 {
267 ; CHECK-LABEL: f12:
268 ; CHECK: sqebr
269 ; CHECK: sqebr
270 ; CHECK: ste
271 ; CHECK: ste
272 ; CHECK: br %r14
274   %sqrt1 = call float @llvm.experimental.constrained.sqrt.f32(
275                         float %f1,
276                         metadata !"round.dynamic",
277                         metadata !"fpexcept.strict") #0
278   %sqrt2 = call float @llvm.experimental.constrained.sqrt.f32(
279                         float %f2,
280                         metadata !"round.dynamic",
281                         metadata !"fpexcept.strict") #0
283   call void @llvm.s390.sfpc(i32 0) #0
285   store float %sqrt1, ptr %ptr1
286   store float %sqrt2, ptr %ptr2
288   ret void
291 ; If the result of any FP operation is unused, it can be removed
292 ; -- except for fpexcept.strict operations.
294 define void @f13(float %f1) {
295 ; CHECK-LABEL: f13:
296 ; CHECK-NOT: sqeb
297 ; CHECK: br %r14
299   %sqrt = call float @llvm.sqrt.f32(float %f1)
301   ret void
304 define void @f14(float %f1) #0 {
305 ; CHECK-LABEL: f14:
306 ; CHECK-NOT: sqeb
307 ; CHECK: br %r14
309   %sqrt = call float @llvm.experimental.constrained.sqrt.f32(
310                         float %f1,
311                         metadata !"round.dynamic",
312                         metadata !"fpexcept.ignore") #0
314   ret void
317 define void @f15(float %f1) #0 {
318 ; CHECK-LABEL: f15:
319 ; CHECK-NOT: sqeb
320 ; CHECK: br %r14
322   %sqrt = call float @llvm.experimental.constrained.sqrt.f32(
323                         float %f1,
324                         metadata !"round.dynamic",
325                         metadata !"fpexcept.maytrap") #0
327   ret void
330 define void @f16(float %f1) #0 {
331 ; CHECK-LABEL: f16:
332 ; CHECK: sqebr
333 ; CHECK: br %r14
335   %sqrt = call float @llvm.experimental.constrained.sqrt.f32(
336                         float %f1,
337                         metadata !"round.dynamic",
338                         metadata !"fpexcept.strict") #0
340   ret void
344 ; Verify that constrained intrinsics and memory operations get their
345 ; chains linked up properly.
347 define void @f17(float %in, ptr %out) #0 {
348 ; CHECK-LABEL: f17:
349 ; CHECK: sqebr
350 ; CHECK: ste
351 ; CHECK: jg bar
352   %sqrt = call float @llvm.experimental.constrained.sqrt.f32(
353                         float %in,
354                         metadata !"round.dynamic",
355                         metadata !"fpexcept.ignore") #0
356   store float %sqrt, ptr %out, align 4
357   tail call void @bar() #0
358   ret void
361 define void @f18(float %in, ptr %out) #0 {
362 ; CHECK-LABEL: f18:
363 ; CHECK: sqebr
364 ; CHECK: ste
365 ; CHECK: jg bar
366   %sqrt = call float @llvm.experimental.constrained.sqrt.f32(
367                         float %in,
368                         metadata !"round.dynamic",
369                         metadata !"fpexcept.ignore") #0
370   store float %sqrt, ptr %out, align 4
371   tail call void @bar() #0
372   ret void
375 define void @f19(float %in, ptr %out) #0 {
376 ; CHECK-LABEL: f19:
377 ; CHECK: sqebr
378 ; CHECK: ste
379 ; CHECK: jg bar
380   %sqrt = call float @llvm.experimental.constrained.sqrt.f32(
381                         float %in,
382                         metadata !"round.dynamic",
383                         metadata !"fpexcept.maytrap") #0
384   store float %sqrt, ptr %out, align 4
385   tail call void @bar() #0
386   ret void
389 define void @f20(float %in, ptr %out) #0 {
390 ; CHECK-LABEL: f20:
391 ; CHECK: sqebr
392 ; CHECK: ste
393 ; CHECK: jg bar
394   %sqrt = call float @llvm.experimental.constrained.sqrt.f32(
395                         float %in,
396                         metadata !"round.dynamic",
397                         metadata !"fpexcept.strict") #0
398   store float %sqrt, ptr %out, align 4
399   tail call void @bar() #0
400   ret void
403 attributes #0 = { strictfp }