blob: e2b2e05a902ae09560b348ebb23179274bb6c380 [file] [log] [blame]
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +00001; Verify that strict FP operations are not rescheduled
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s
4
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +00005declare float @llvm.experimental.constrained.sqrt.f32(float, metadata, metadata)
6declare float @llvm.sqrt.f32(float)
7declare void @llvm.s390.sfpc(i32)
8
Ulrich Weigand450c62e2019-07-16 15:55:45 +00009; The basic assumption of all following tests is that on z13, we never
10; want to see two square root instructions directly in a row, so the
11; post-RA scheduler will always schedule something else in between
12; whenever possible.
13
14; We can move any FP operation across a (normal) store.
15
16define void @f1(float %f1, float %f2, float *%ptr1, float *%ptr2) {
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +000017; CHECK-LABEL: f1:
18; CHECK: sqebr
Ulrich Weigand450c62e2019-07-16 15:55:45 +000019; CHECK: ste
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +000020; CHECK: sqebr
Ulrich Weigand450c62e2019-07-16 15:55:45 +000021; CHECK: ste
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +000022; CHECK: br %r14
23
Ulrich Weigand450c62e2019-07-16 15:55:45 +000024 %sqrt1 = call float @llvm.sqrt.f32(float %f1)
25 %sqrt2 = call float @llvm.sqrt.f32(float %f2)
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +000026
Ulrich Weigand450c62e2019-07-16 15:55:45 +000027 store float %sqrt1, float *%ptr1
28 store float %sqrt2, float *%ptr2
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +000029
30 ret void
31}
32
Kevin P. Neal68b80522019-10-04 17:03:46 +000033define void @f2(float %f1, float %f2, float *%ptr1, float *%ptr2) #0 {
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +000034; CHECK-LABEL: f2:
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +000035; CHECK: sqebr
Ulrich Weigand450c62e2019-07-16 15:55:45 +000036; CHECK: ste
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +000037; CHECK: sqebr
Ulrich Weigand450c62e2019-07-16 15:55:45 +000038; CHECK: ste
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +000039; CHECK: br %r14
40
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +000041 %sqrt1 = call float @llvm.experimental.constrained.sqrt.f32(
Ulrich Weigand450c62e2019-07-16 15:55:45 +000042 float %f1,
43 metadata !"round.dynamic",
Kevin P. Neal68b80522019-10-04 17:03:46 +000044 metadata !"fpexcept.ignore") #0
Ulrich Weigand450c62e2019-07-16 15:55:45 +000045 %sqrt2 = call float @llvm.experimental.constrained.sqrt.f32(
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +000046 float %f2,
47 metadata !"round.dynamic",
Kevin P. Neal68b80522019-10-04 17:03:46 +000048 metadata !"fpexcept.ignore") #0
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +000049
Ulrich Weigand450c62e2019-07-16 15:55:45 +000050 store float %sqrt1, float *%ptr1
51 store float %sqrt2, float *%ptr2
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +000052
53 ret void
54}
55
Kevin P. Neal68b80522019-10-04 17:03:46 +000056define void @f3(float %f1, float %f2, float *%ptr1, float *%ptr2) #0 {
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +000057; CHECK-LABEL: f3:
58; CHECK: sqebr
Ulrich Weigand450c62e2019-07-16 15:55:45 +000059; CHECK: ste
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +000060; CHECK: sqebr
Ulrich Weigand450c62e2019-07-16 15:55:45 +000061; CHECK: ste
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +000062; CHECK: br %r14
63
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +000064 %sqrt1 = call float @llvm.experimental.constrained.sqrt.f32(
Ulrich Weigand450c62e2019-07-16 15:55:45 +000065 float %f1,
66 metadata !"round.dynamic",
Ulrich Weigand14cd4a52020-01-07 12:43:33 +010067 metadata !"fpexcept.maytrap") #0
68 %sqrt2 = call float @llvm.experimental.constrained.sqrt.f32(
69 float %f2,
70 metadata !"round.dynamic",
71 metadata !"fpexcept.maytrap") #0
72
73 store float %sqrt1, float *%ptr1
74 store float %sqrt2, float *%ptr2
75
76 ret void
77}
78
79define void @f4(float %f1, float %f2, float *%ptr1, float *%ptr2) #0 {
80; CHECK-LABEL: f4:
81; CHECK: sqebr
82; CHECK: ste
83; CHECK: sqebr
84; CHECK: ste
85; CHECK: br %r14
86
87 %sqrt1 = call float @llvm.experimental.constrained.sqrt.f32(
88 float %f1,
89 metadata !"round.dynamic",
Kevin P. Neal68b80522019-10-04 17:03:46 +000090 metadata !"fpexcept.strict") #0
Ulrich Weigand450c62e2019-07-16 15:55:45 +000091 %sqrt2 = call float @llvm.experimental.constrained.sqrt.f32(
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +000092 float %f2,
93 metadata !"round.dynamic",
Kevin P. Neal68b80522019-10-04 17:03:46 +000094 metadata !"fpexcept.strict") #0
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +000095
Ulrich Weigand450c62e2019-07-16 15:55:45 +000096 store float %sqrt1, float *%ptr1
97 store float %sqrt2, float *%ptr2
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +000098
99 ret void
100}
101
Ulrich Weigand450c62e2019-07-16 15:55:45 +0000102
103; We can move a non-strict FP operation or a fpexcept.ignore
Ulrich Weigand14cd4a52020-01-07 12:43:33 +0100104; operation even across a volatile store, but not a fpexcept.maytrap
105; or fpexcept.strict operation.
Ulrich Weigand450c62e2019-07-16 15:55:45 +0000106
Ulrich Weigand14cd4a52020-01-07 12:43:33 +0100107define void @f5(float %f1, float %f2, float *%ptr1, float *%ptr2) {
108; CHECK-LABEL: f5:
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +0000109; CHECK: sqebr
Ulrich Weigand450c62e2019-07-16 15:55:45 +0000110; CHECK: ste
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +0000111; CHECK: sqebr
Ulrich Weigand450c62e2019-07-16 15:55:45 +0000112; CHECK: ste
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +0000113; CHECK: br %r14
114
Ulrich Weigand450c62e2019-07-16 15:55:45 +0000115 %sqrt1 = call float @llvm.sqrt.f32(float %f1)
116 %sqrt2 = call float @llvm.sqrt.f32(float %f2)
117
118 store volatile float %sqrt1, float *%ptr1
119 store volatile float %sqrt2, float *%ptr2
120
121 ret void
122}
123
Ulrich Weigand14cd4a52020-01-07 12:43:33 +0100124define void @f6(float %f1, float %f2, float *%ptr1, float *%ptr2) #0 {
125; CHECK-LABEL: f6:
Ulrich Weigand450c62e2019-07-16 15:55:45 +0000126; CHECK: sqebr
127; CHECK: ste
128; CHECK: sqebr
129; CHECK: ste
130; CHECK: br %r14
131
132 %sqrt1 = call float @llvm.experimental.constrained.sqrt.f32(
133 float %f1,
134 metadata !"round.dynamic",
Kevin P. Neal68b80522019-10-04 17:03:46 +0000135 metadata !"fpexcept.ignore") #0
Ulrich Weigand450c62e2019-07-16 15:55:45 +0000136 %sqrt2 = call float @llvm.experimental.constrained.sqrt.f32(
137 float %f2,
138 metadata !"round.dynamic",
Kevin P. Neal68b80522019-10-04 17:03:46 +0000139 metadata !"fpexcept.ignore") #0
Ulrich Weigand450c62e2019-07-16 15:55:45 +0000140
141 store volatile float %sqrt1, float *%ptr1
142 store volatile float %sqrt2, float *%ptr2
143
144 ret void
145}
146
Ulrich Weigand14cd4a52020-01-07 12:43:33 +0100147define void @f7(float %f1, float %f2, float *%ptr1, float *%ptr2) #0 {
148; CHECK-LABEL: f7:
149; CHECK: sqebr
150; CHECK: sqebr
151; CHECK: ste
152; CHECK: ste
153; CHECK: br %r14
154
155 %sqrt1 = call float @llvm.experimental.constrained.sqrt.f32(
156 float %f1,
157 metadata !"round.dynamic",
158 metadata !"fpexcept.maytrap") #0
159 %sqrt2 = call float @llvm.experimental.constrained.sqrt.f32(
160 float %f2,
161 metadata !"round.dynamic",
162 metadata !"fpexcept.maytrap") #0
163
164 store volatile float %sqrt1, float *%ptr1
165 store volatile float %sqrt2, float *%ptr2
166
167 ret void
168}
169
170define void @f8(float %f1, float %f2, float *%ptr1, float *%ptr2) #0 {
171; CHECK-LABEL: f8:
Ulrich Weigand450c62e2019-07-16 15:55:45 +0000172; CHECK: sqebr
173; CHECK: sqebr
174; CHECK: ste
175; CHECK: ste
176; CHECK: br %r14
177
178 %sqrt1 = call float @llvm.experimental.constrained.sqrt.f32(
179 float %f1,
180 metadata !"round.dynamic",
Kevin P. Neal68b80522019-10-04 17:03:46 +0000181 metadata !"fpexcept.strict") #0
Ulrich Weigand450c62e2019-07-16 15:55:45 +0000182 %sqrt2 = call float @llvm.experimental.constrained.sqrt.f32(
183 float %f2,
184 metadata !"round.dynamic",
Kevin P. Neal68b80522019-10-04 17:03:46 +0000185 metadata !"fpexcept.strict") #0
Ulrich Weigand450c62e2019-07-16 15:55:45 +0000186
187 store volatile float %sqrt1, float *%ptr1
188 store volatile float %sqrt2, float *%ptr2
189
190 ret void
191}
192
193
194; No variant of FP operations can be scheduled across a SPFC.
195
Ulrich Weigand14cd4a52020-01-07 12:43:33 +0100196define void @f9(float %f1, float %f2, float *%ptr1, float *%ptr2) {
197; CHECK-LABEL: f9:
Ulrich Weigand450c62e2019-07-16 15:55:45 +0000198; CHECK: sqebr
199; CHECK: sqebr
200; CHECK: ste
201; CHECK: ste
202; CHECK: br %r14
203
204 %sqrt1 = call float @llvm.sqrt.f32(float %f1)
205 %sqrt2 = call float @llvm.sqrt.f32(float %f2)
206
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +0000207 call void @llvm.s390.sfpc(i32 0)
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +0000208
Ulrich Weigand450c62e2019-07-16 15:55:45 +0000209 store float %sqrt1, float *%ptr1
210 store float %sqrt2, float *%ptr2
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +0000211
Ulrich Weigand450c62e2019-07-16 15:55:45 +0000212 ret void
213}
214
Ulrich Weigand14cd4a52020-01-07 12:43:33 +0100215define void @f10(float %f1, float %f2, float *%ptr1, float *%ptr2) #0 {
216; CHECK-LABEL: f10:
Ulrich Weigand450c62e2019-07-16 15:55:45 +0000217; CHECK: sqebr
218; CHECK: sqebr
219; CHECK: ste
220; CHECK: ste
221; CHECK: br %r14
222
223 %sqrt1 = call float @llvm.experimental.constrained.sqrt.f32(
224 float %f1,
225 metadata !"round.dynamic",
Kevin P. Neal68b80522019-10-04 17:03:46 +0000226 metadata !"fpexcept.ignore") #0
Ulrich Weigand450c62e2019-07-16 15:55:45 +0000227 %sqrt2 = call float @llvm.experimental.constrained.sqrt.f32(
228 float %f2,
229 metadata !"round.dynamic",
Kevin P. Neal68b80522019-10-04 17:03:46 +0000230 metadata !"fpexcept.ignore") #0
Ulrich Weigand450c62e2019-07-16 15:55:45 +0000231
Kevin P. Neal68b80522019-10-04 17:03:46 +0000232 call void @llvm.s390.sfpc(i32 0) #0
Ulrich Weigand450c62e2019-07-16 15:55:45 +0000233
234 store float %sqrt1, float *%ptr1
235 store float %sqrt2, float *%ptr2
236
237 ret void
238}
239
Ulrich Weigand14cd4a52020-01-07 12:43:33 +0100240define void @f11(float %f1, float %f2, float *%ptr1, float *%ptr2) #0 {
241; CHECK-LABEL: f11:
242; CHECK: sqebr
243; CHECK: sqebr
244; CHECK: ste
245; CHECK: ste
246; CHECK: br %r14
247
248 %sqrt1 = call float @llvm.experimental.constrained.sqrt.f32(
249 float %f1,
250 metadata !"round.dynamic",
251 metadata !"fpexcept.maytrap") #0
252 %sqrt2 = call float @llvm.experimental.constrained.sqrt.f32(
253 float %f2,
254 metadata !"round.dynamic",
255 metadata !"fpexcept.maytrap") #0
256
257 call void @llvm.s390.sfpc(i32 0) #0
258
259 store float %sqrt1, float *%ptr1
260 store float %sqrt2, float *%ptr2
261
262 ret void
263}
264
265define void @f12(float %f1, float %f2, float *%ptr1, float *%ptr2) #0 {
266; CHECK-LABEL: f12:
Ulrich Weigand450c62e2019-07-16 15:55:45 +0000267; CHECK: sqebr
268; CHECK: sqebr
269; CHECK: ste
270; CHECK: ste
271; CHECK: br %r14
272
273 %sqrt1 = call float @llvm.experimental.constrained.sqrt.f32(
274 float %f1,
275 metadata !"round.dynamic",
Kevin P. Neal68b80522019-10-04 17:03:46 +0000276 metadata !"fpexcept.strict") #0
Ulrich Weigand450c62e2019-07-16 15:55:45 +0000277 %sqrt2 = call float @llvm.experimental.constrained.sqrt.f32(
278 float %f2,
279 metadata !"round.dynamic",
Kevin P. Neal68b80522019-10-04 17:03:46 +0000280 metadata !"fpexcept.strict") #0
Ulrich Weigand450c62e2019-07-16 15:55:45 +0000281
Kevin P. Neal68b80522019-10-04 17:03:46 +0000282 call void @llvm.s390.sfpc(i32 0) #0
Ulrich Weigand450c62e2019-07-16 15:55:45 +0000283
284 store float %sqrt1, float *%ptr1
285 store float %sqrt2, float *%ptr2
Ulrich Weigand6c5d5ce2019-06-05 22:33:10 +0000286
287 ret void
288}
289
Ulrich Weigand04a86962020-01-13 14:37:07 +0100290; If the result of any FP operation is unused, it can be removed
291; -- except for fpexcept.strict operations.
292
293define void @f13(float %f1) {
294; CHECK-LABEL: f13:
295; CHECK-NOT: sqeb
296; CHECK: br %r14
297
298 %sqrt = call float @llvm.sqrt.f32(float %f1)
299
300 ret void
301}
302
303define void @f14(float %f1) {
304; CHECK-LABEL: f14:
305; CHECK-NOT: sqeb
306; CHECK: br %r14
307
308 %sqrt = call float @llvm.experimental.constrained.sqrt.f32(
309 float %f1,
310 metadata !"round.dynamic",
311 metadata !"fpexcept.ignore") #0
312
313 ret void
314}
315
316define void @f15(float %f1) {
317; CHECK-LABEL: f15:
318; CHECK-NOT: sqeb
319; CHECK: br %r14
320
321 %sqrt = call float @llvm.experimental.constrained.sqrt.f32(
322 float %f1,
323 metadata !"round.dynamic",
324 metadata !"fpexcept.maytrap") #0
325
326 ret void
327}
328
329define void @f16(float %f1) {
330; CHECK-LABEL: f16:
331; CHECK: sqebr
332; CHECK: br %r14
333
334 %sqrt = call float @llvm.experimental.constrained.sqrt.f32(
335 float %f1,
336 metadata !"round.dynamic",
337 metadata !"fpexcept.strict") #0
338
339 ret void
340}
341
Kevin P. Neal68b80522019-10-04 17:03:46 +0000342attributes #0 = { strictfp }