1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
12 define float @fsub_x_p0_defaultenv(float %a) #0 {
13 ; CHECK-LABEL: @fsub_x_p0_defaultenv(
14 ; CHECK-NEXT: ret float [[A:%.*]]
16 %ret = call float @llvm.experimental.constrained.fsub.f32(float %a, float 0.0, metadata !"round.tonearest", metadata !"fpexcept.ignore")
20 ; Missing nnan: must not fire.
21 define float @fsub_x_p0_ebmaytrap(float %a) #0 {
22 ; CHECK-LABEL: @fsub_x_p0_ebmaytrap(
23 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float 0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
24 ; CHECK-NEXT: ret float [[RET]]
26 %ret = call float @llvm.experimental.constrained.fsub.f32(float %a, float 0.0, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
30 define float @fsub_nnan_x_p0_ebmaytrap(float %a) #0 {
31 ; CHECK-LABEL: @fsub_nnan_x_p0_ebmaytrap(
32 ; CHECK-NEXT: ret float [[A:%.*]]
34 %ret = call nnan float @llvm.experimental.constrained.fsub.f32(float %a, float 0.0, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
38 ; Missing nnan: must not fire.
39 define float @fsub_x_p0_ebstrict(float %a) #0 {
40 ; CHECK-LABEL: @fsub_x_p0_ebstrict(
41 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float 0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict")
42 ; CHECK-NEXT: ret float [[RET]]
44 %ret = call float @llvm.experimental.constrained.fsub.f32(float %a, float 0.0, metadata !"round.tonearest", metadata !"fpexcept.strict")
48 ; The instruction is expected to remain, but the result isn't used.
49 define float @fsub_nnan_x_p0_ebstrict(float %a) #0 {
50 ; CHECK-LABEL: @fsub_nnan_x_p0_ebstrict(
51 ; CHECK-NEXT: [[RET:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float 0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict")
52 ; CHECK-NEXT: ret float [[A]]
54 %ret = call nnan float @llvm.experimental.constrained.fsub.f32(float %a, float 0.0, metadata !"round.tonearest", metadata !"fpexcept.strict")
58 ; Test with a fast math flag set but that flag is not "nnan".
59 define float @fsub_ninf_x_p0_ebstrict(float %a) #0 {
60 ; CHECK-LABEL: @fsub_ninf_x_p0_ebstrict(
61 ; CHECK-NEXT: [[RET:%.*]] = call ninf float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float 0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict")
62 ; CHECK-NEXT: ret float [[RET]]
64 %ret = call ninf float @llvm.experimental.constrained.fsub.f32(float %a, float 0.0, metadata !"round.tonearest", metadata !"fpexcept.strict")
68 ; Round to -inf and if x is zero then the result is -0.0: must not fire
69 define float @fsub_x_p0_neginf(float %a) #0 {
70 ; CHECK-LABEL: @fsub_x_p0_neginf(
71 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float 0.000000e+00, metadata !"round.downward", metadata !"fpexcept.ignore")
72 ; CHECK-NEXT: ret float [[RET]]
74 %ret = call float @llvm.experimental.constrained.fsub.f32(float %a, float 0.0, metadata !"round.downward", metadata !"fpexcept.ignore")
78 ; Dynamic rounding means the rounding mode might be to -inf:
79 ; Round to -inf and if x is zero then the result is -0.0: must not fire
80 define float @fsub_x_p0_dynamic(float %a) #0 {
81 ; CHECK-LABEL: @fsub_x_p0_dynamic(
82 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float 0.000000e+00, metadata !"round.dynamic", metadata !"fpexcept.ignore")
83 ; CHECK-NEXT: ret float [[RET]]
85 %ret = call float @llvm.experimental.constrained.fsub.f32(float %a, float 0.0, metadata !"round.dynamic", metadata !"fpexcept.ignore")
89 ; With nsz we don't have to worry about -0.0 so the transform is valid.
90 define float @fsub_nsz_x_p0_neginf(float %a) #0 {
91 ; CHECK-LABEL: @fsub_nsz_x_p0_neginf(
92 ; CHECK-NEXT: ret float [[A:%.*]]
94 %ret = call nsz float @llvm.experimental.constrained.fsub.f32(float %a, float 0.0, metadata !"round.downward", metadata !"fpexcept.ignore")
98 ; With nsz we don't have to worry about -0.0 so the transform is valid.
99 define float @fsub_nsz_x_p0_dynamic(float %a) #0 {
100 ; CHECK-LABEL: @fsub_nsz_x_p0_dynamic(
101 ; CHECK-NEXT: ret float [[A:%.*]]
103 %ret = call nsz float @llvm.experimental.constrained.fsub.f32(float %a, float 0.0, metadata !"round.dynamic", metadata !"fpexcept.ignore")
108 ; fsub X, -0 ==> X, when we know X is not -0
109 ; (fast math flag: nsz)
112 define float @fold_fsub_nsz_x_n0_defaultenv(float %a) #0 {
113 ; CHECK-LABEL: @fold_fsub_nsz_x_n0_defaultenv(
114 ; CHECK-NEXT: ret float [[A:%.*]]
116 %sub = call nsz float @llvm.experimental.constrained.fsub.f32(float %a, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.ignore")
120 ; Missing nnan: must not fire.
121 define float @fold_fsub_nsz_x_n0_ebmaytrap(float %a) #0 {
122 ; CHECK-LABEL: @fold_fsub_nsz_x_n0_ebmaytrap(
123 ; CHECK-NEXT: [[SUB:%.*]] = call nsz float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float -0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
124 ; CHECK-NEXT: ret float [[SUB]]
126 %sub = call nsz float @llvm.experimental.constrained.fsub.f32(float %a, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
130 define float @fold_fsub_nnan_nsz_x_n0_ebmaytrap(float %a) #0 {
131 ; CHECK-LABEL: @fold_fsub_nnan_nsz_x_n0_ebmaytrap(
132 ; CHECK-NEXT: ret float [[A:%.*]]
134 %sub = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float %a, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
138 ; Missing nnan: must not fire.
139 define float @fold_fsub_nsz_x_n0_ebstrict(float %a) #0 {
140 ; CHECK-LABEL: @fold_fsub_nsz_x_n0_ebstrict(
141 ; CHECK-NEXT: [[SUB:%.*]] = call nsz float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float -0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict")
142 ; CHECK-NEXT: ret float [[SUB]]
144 %sub = call nsz float @llvm.experimental.constrained.fsub.f32(float %a, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.strict")
148 ; The instruction is expected to remain, but the result isn't used.
149 define float @fold_fsub_nsz_nnan_x_n0_ebstrict(float %a) #0 {
150 ; CHECK-LABEL: @fold_fsub_nsz_nnan_x_n0_ebstrict(
151 ; CHECK-NEXT: [[SUB:%.*]] = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float -0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict")
152 ; CHECK-NEXT: ret float [[A]]
154 %sub = call nsz nnan float @llvm.experimental.constrained.fsub.f32(float %a, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.strict")
159 ; fsub X, -0 ==> X, when we know X is not -0
163 define float @fold_fsub_fabs_x_n0_defaultenv(float %a) #0 {
164 ; CHECK-LABEL: @fold_fsub_fabs_x_n0_defaultenv(
165 ; CHECK-NEXT: [[ABSA:%.*]] = call float @llvm.fabs.f32(float [[A:%.*]]) #[[ATTR0:[0-9]+]]
166 ; CHECK-NEXT: ret float [[ABSA]]
168 %absa = call float @llvm.fabs.f32(float %a) #0
169 %sub = call float @llvm.experimental.constrained.fsub.f32(float %absa, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.ignore")
173 ; Missing nnan: must not fire.
174 define float @fold_fsub_fabs_x_n0_ebmaytrap(float %a) #0 {
175 ; CHECK-LABEL: @fold_fsub_fabs_x_n0_ebmaytrap(
176 ; CHECK-NEXT: [[ABSA:%.*]] = call float @llvm.fabs.f32(float [[A:%.*]]) #[[ATTR0]]
177 ; CHECK-NEXT: [[SUB:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[ABSA]], float -0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
178 ; CHECK-NEXT: ret float [[SUB]]
180 %absa = call float @llvm.fabs.f32(float %a) #0
181 %sub = call float @llvm.experimental.constrained.fsub.f32(float %absa, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
185 define float @fold_fsub_fabs_nnan_x_n0_ebmaytrap(float %a) #0 {
186 ; CHECK-LABEL: @fold_fsub_fabs_nnan_x_n0_ebmaytrap(
187 ; CHECK-NEXT: [[ABSA:%.*]] = call float @llvm.fabs.f32(float [[A:%.*]]) #[[ATTR0]]
188 ; CHECK-NEXT: ret float [[ABSA]]
190 %absa = call float @llvm.fabs.f32(float %a) #0
191 %sub = call nnan float @llvm.experimental.constrained.fsub.f32(float %absa, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
195 ; Missing nnan: must not fire.
196 define float @fold_fsub_fabs_x_n0_ebstrict(float %a) #0 {
197 ; CHECK-LABEL: @fold_fsub_fabs_x_n0_ebstrict(
198 ; CHECK-NEXT: [[ABSA:%.*]] = call float @llvm.fabs.f32(float [[A:%.*]]) #[[ATTR0]]
199 ; CHECK-NEXT: [[SUB:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[ABSA]], float -0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict")
200 ; CHECK-NEXT: ret float [[SUB]]
202 %absa = call float @llvm.fabs.f32(float %a) #0
203 %sub = call float @llvm.experimental.constrained.fsub.f32(float %absa, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.strict")
207 ; The instruction is expected to remain, but the result isn't used.
208 define float @fold_fsub_fabs_nnan_x_n0_ebstrict(float %a) #0 {
209 ; CHECK-LABEL: @fold_fsub_fabs_nnan_x_n0_ebstrict(
210 ; CHECK-NEXT: [[ABSA:%.*]] = call float @llvm.fabs.f32(float [[A:%.*]]) #[[ATTR0]]
211 ; CHECK-NEXT: [[SUB:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float [[ABSA]], float -0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict")
212 ; CHECK-NEXT: ret float [[ABSA]]
214 %absa = call float @llvm.fabs.f32(float %a) #0
215 %sub = call nnan float @llvm.experimental.constrained.fsub.f32(float %absa, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.strict")
219 define float @fold_fsub_sitofp_x_n0_defaultenv(i32 %a) #0 {
220 ; CHECK-LABEL: @fold_fsub_sitofp_x_n0_defaultenv(
221 ; CHECK-NEXT: [[FPA:%.*]] = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore")
222 ; CHECK-NEXT: ret float [[FPA]]
224 %fpa = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.ignore")
225 %sub = call float @llvm.experimental.constrained.fsub.f32(float %fpa, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.ignore")
230 ; fsub -0.0, (fneg X) ==> X
233 define float @fsub_fneg_n0_fnX_defaultenv(float %a) #0 {
234 ; CHECK-LABEL: @fsub_fneg_n0_fnX_defaultenv(
235 ; CHECK-NEXT: ret float [[A:%.*]]
237 %nega = fneg float %a
238 %ret = call float @llvm.experimental.constrained.fsub.f32(float -0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.ignore")
242 ; Missing nnan: must not fire.
243 define float @fsub_fneg_n0_fnX_ebmaytrap(float %a) #0 {
244 ; CHECK-LABEL: @fsub_fneg_n0_fnX_ebmaytrap(
245 ; CHECK-NEXT: [[NEGA:%.*]] = fneg float [[A:%.*]]
246 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.maytrap")
247 ; CHECK-NEXT: ret float [[RET]]
249 %nega = fneg float %a
250 %ret = call float @llvm.experimental.constrained.fsub.f32(float -0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
254 define float @fsub_fneg_nnan_n0_fnX_ebmaytrap(float %a) #0 {
255 ; CHECK-LABEL: @fsub_fneg_nnan_n0_fnX_ebmaytrap(
256 ; CHECK-NEXT: ret float [[A:%.*]]
258 %nega = fneg float %a
259 %ret = call nnan float @llvm.experimental.constrained.fsub.f32(float -0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
263 ; Missing nnan: must not fire.
264 define float @fsub_fneg_n0_fnX_ebstrict(float %a) #0 {
265 ; CHECK-LABEL: @fsub_fneg_n0_fnX_ebstrict(
266 ; CHECK-NEXT: [[NEGA:%.*]] = fneg float [[A:%.*]]
267 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.strict")
268 ; CHECK-NEXT: ret float [[RET]]
270 %nega = fneg float %a
271 %ret = call float @llvm.experimental.constrained.fsub.f32(float -0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.strict")
275 ; The instruction is expected to remain, but the result isn't used.
276 define float @fsub_fneg_nnan_n0_fnX_ebstrict(float %a) #0 {
277 ; CHECK-LABEL: @fsub_fneg_nnan_n0_fnX_ebstrict(
278 ; CHECK-NEXT: [[NEGA:%.*]] = fneg float [[A:%.*]]
279 ; CHECK-NEXT: [[RET:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.strict")
280 ; CHECK-NEXT: ret float [[A]]
282 %nega = fneg float %a
283 %ret = call nnan float @llvm.experimental.constrained.fsub.f32(float -0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.strict")
288 ; fsub -0.0, (fsub -0.0, X) ==> X
291 ; TODO: This won't fire without m_FNeg() knowing the constrained intrinsics.
292 define float @fsub_fsub_n0_fnX_defaultenv(float %a) #0 {
293 ; CHECK-LABEL: @fsub_fsub_n0_fnX_defaultenv(
294 ; CHECK-NEXT: [[NEGA:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore")
295 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.ignore")
296 ; CHECK-NEXT: ret float [[RET]]
298 %nega = call float @llvm.experimental.constrained.fsub.f32(float -0.0, float %a, metadata !"round.tonearest", metadata !"fpexcept.ignore")
299 %ret = call float @llvm.experimental.constrained.fsub.f32(float -0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.ignore")
303 ; Missing nnan: must not fire.
304 define float @fsub_fsub_n0_fnX_ebmaytrap(float %a) #0 {
305 ; CHECK-LABEL: @fsub_fsub_n0_fnX_ebmaytrap(
306 ; CHECK-NEXT: [[NEGA:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap")
307 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.maytrap")
308 ; CHECK-NEXT: ret float [[RET]]
310 %nega = call float @llvm.experimental.constrained.fsub.f32(float -0.0, float %a, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
311 %ret = call float @llvm.experimental.constrained.fsub.f32(float -0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
315 ; TODO: This won't fire without m_FNeg() knowing the constrained intrinsics.
316 define float @fsub_fsub_nnan_n0_fnX_ebmaytrap(float %a) #0 {
317 ; CHECK-LABEL: @fsub_fsub_nnan_n0_fnX_ebmaytrap(
318 ; CHECK-NEXT: [[NEGA:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap")
319 ; CHECK-NEXT: [[RET:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.maytrap")
320 ; CHECK-NEXT: ret float [[RET]]
322 %nega = call float @llvm.experimental.constrained.fsub.f32(float -0.0, float %a, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
323 %ret = call nnan float @llvm.experimental.constrained.fsub.f32(float -0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
327 ; Missing nnan: must not fire.
328 define float @fsub_fsub_n0_fnX_ebstrict(float %a) #0 {
329 ; CHECK-LABEL: @fsub_fsub_n0_fnX_ebstrict(
330 ; CHECK-NEXT: [[NEGA:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict")
331 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.strict")
332 ; CHECK-NEXT: ret float [[RET]]
334 %nega = call float @llvm.experimental.constrained.fsub.f32(float -0.0, float %a, metadata !"round.tonearest", metadata !"fpexcept.strict")
335 %ret = call float @llvm.experimental.constrained.fsub.f32(float -0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.strict")
339 ; TODO: This won't fire without m_FNeg() knowing the constrained intrinsics.
340 define float @fsub_fsub_nnan_n0_fnX_ebstrict(float %a) #0 {
341 ; CHECK-LABEL: @fsub_fsub_nnan_n0_fnX_ebstrict(
342 ; CHECK-NEXT: [[NEGA:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict")
343 ; CHECK-NEXT: [[RET:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.strict")
344 ; CHECK-NEXT: ret float [[RET]]
346 %nega = call nnan float @llvm.experimental.constrained.fsub.f32(float -0.0, float %a, metadata !"round.tonearest", metadata !"fpexcept.strict")
347 %ret = call nnan float @llvm.experimental.constrained.fsub.f32(float -0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.strict")
352 ; fsub 0.0, (fneg X) ==> X if signed zeros are ignored.
355 define float @fsub_fneg_nsz_p0_fnX_defaultenv(float %a) #0 {
356 ; CHECK-LABEL: @fsub_fneg_nsz_p0_fnX_defaultenv(
357 ; CHECK-NEXT: ret float [[A:%.*]]
359 %nega = fneg float %a
360 %ret = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.ignore")
364 ; Missing nnan: must not fire.
365 define float @fsub_fneg_nsz_p0_fnX_ebmaytrap(float %a) #0 {
366 ; CHECK-LABEL: @fsub_fneg_nsz_p0_fnX_ebmaytrap(
367 ; CHECK-NEXT: [[NEGA:%.*]] = fneg float [[A:%.*]]
368 ; CHECK-NEXT: [[RET:%.*]] = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.maytrap")
369 ; CHECK-NEXT: ret float [[RET]]
371 %nega = fneg float %a
372 %ret = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
376 define float @fsub_fneg_nsz_nnan_p0_fnX_ebmaytrap(float %a) #0 {
377 ; CHECK-LABEL: @fsub_fneg_nsz_nnan_p0_fnX_ebmaytrap(
378 ; CHECK-NEXT: ret float [[A:%.*]]
380 %nega = fneg float %a
381 %ret = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
385 ; Missing nnan: must not fire.
386 define float @fsub_fneg_nsz_p0_fnX_ebstrict(float %a) #0 {
387 ; CHECK-LABEL: @fsub_fneg_nsz_p0_fnX_ebstrict(
388 ; CHECK-NEXT: [[NEGA:%.*]] = fneg float [[A:%.*]]
389 ; CHECK-NEXT: [[RET:%.*]] = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.strict")
390 ; CHECK-NEXT: ret float [[RET]]
392 %nega = fneg float %a
393 %ret = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.strict")
397 ; The instruction is expected to remain, but the result isn't used.
398 define float @fsub_fneg_nnan_nsz_p0_fnX_ebstrict(float %a) #0 {
399 ; CHECK-LABEL: @fsub_fneg_nnan_nsz_p0_fnX_ebstrict(
400 ; CHECK-NEXT: [[NEGA:%.*]] = fneg float [[A:%.*]]
401 ; CHECK-NEXT: [[RET:%.*]] = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.strict")
402 ; CHECK-NEXT: ret float [[A]]
404 %nega = fneg float %a
405 %ret = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.strict")
410 ; fsub 0.0, (fsub 0.0, X) ==> X if signed zeros are ignored.
413 ; TODO: Need constrained intrinsic support in m_FNeg() and m_FSub to fire.
414 define float @fsub_fsub_p0_nsz_fnX_defaultenv(float %a) #0 {
415 ; CHECK-LABEL: @fsub_fsub_p0_nsz_fnX_defaultenv(
416 ; CHECK-NEXT: [[NEGA:%.*]] = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore")
417 ; CHECK-NEXT: [[RET:%.*]] = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.ignore")
418 ; CHECK-NEXT: ret float [[RET]]
420 %nega = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %a, metadata !"round.tonearest", metadata !"fpexcept.ignore")
421 %ret = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.ignore")
425 ; Missing nnan: must not fire.
426 define float @fsub_fsub_nsz_p0_fnX_ebmaytrap(float %a) #0 {
427 ; CHECK-LABEL: @fsub_fsub_nsz_p0_fnX_ebmaytrap(
428 ; CHECK-NEXT: [[NEGA:%.*]] = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap")
429 ; CHECK-NEXT: [[RET:%.*]] = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.maytrap")
430 ; CHECK-NEXT: ret float [[RET]]
432 %nega = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %a, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
433 %ret = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
437 ; TODO: Need constrained intrinsic support in m_FNeg() and m_FSub to fire.
438 define float @fsub_fsub_nnan_nsz_p0_fnX_ebmaytrap(float %a) #0 {
439 ; CHECK-LABEL: @fsub_fsub_nnan_nsz_p0_fnX_ebmaytrap(
440 ; CHECK-NEXT: [[NEGA:%.*]] = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap")
441 ; CHECK-NEXT: [[RET:%.*]] = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.maytrap")
442 ; CHECK-NEXT: ret float [[RET]]
444 %nega = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %a, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
445 %ret = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
449 ; Missing nnan: must not fire.
450 define float @fsub_fsub_nsz_p0_fnX_ebstrict(float %a) #0 {
451 ; CHECK-LABEL: @fsub_fsub_nsz_p0_fnX_ebstrict(
452 ; CHECK-NEXT: [[NEGA:%.*]] = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict")
453 ; CHECK-NEXT: [[RET:%.*]] = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.strict")
454 ; CHECK-NEXT: ret float [[RET]]
456 %nega = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %a, metadata !"round.tonearest", metadata !"fpexcept.strict")
457 %ret = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.strict")
461 ; TODO: Need constrained intrinsic support in m_FNeg() and m_FSub to fire.
462 define float @fsub_fsub_nnan_nsz_p0_fnX_ebstrict(float %a) #0 {
463 ; CHECK-LABEL: @fsub_fsub_nnan_nsz_p0_fnX_ebstrict(
464 ; CHECK-NEXT: [[NEGA:%.*]] = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict")
465 ; CHECK-NEXT: [[RET:%.*]] = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.strict")
466 ; CHECK-NEXT: ret float [[RET]]
468 %nega = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %a, metadata !"round.tonearest", metadata !"fpexcept.strict")
469 %ret = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.strict")
474 ; fsub nnan x, x ==> 0.0
477 ; Missing nnan: must not fire.
478 define float @fsub_x_x_defaultenv(float %a) #0 {
479 ; CHECK-LABEL: @fsub_x_x_defaultenv(
480 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float [[A]], metadata !"round.tonearest", metadata !"fpexcept.ignore")
481 ; CHECK-NEXT: ret float [[RET]]
483 %ret = call float @llvm.experimental.constrained.fsub.f32(float %a, float %a, metadata !"round.tonearest", metadata !"fpexcept.ignore")
487 define float @fsub_nnan_x_x_defaultenv(float %a) #0 {
488 ; CHECK-LABEL: @fsub_nnan_x_x_defaultenv(
489 ; CHECK-NEXT: ret float 0.000000e+00
491 %ret = call nnan float @llvm.experimental.constrained.fsub.f32(float %a, float %a, metadata !"round.tonearest", metadata !"fpexcept.ignore")
495 ; Missing nnan: must not fire.
496 define float @fsub_x_x_ebmaytrap(float %a) #0 {
497 ; CHECK-LABEL: @fsub_x_x_ebmaytrap(
498 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float [[A]], metadata !"round.tonearest", metadata !"fpexcept.maytrap")
499 ; CHECK-NEXT: ret float [[RET]]
501 %ret = call float @llvm.experimental.constrained.fsub.f32(float %a, float %a, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
505 ; TODO: This will fold if we allow non-default floating point environments.
506 define float @fsub_nnan_x_x_ebmaytrap(float %a) #0 {
507 ; CHECK-LABEL: @fsub_nnan_x_x_ebmaytrap(
508 ; CHECK-NEXT: [[RET:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float [[A]], metadata !"round.tonearest", metadata !"fpexcept.maytrap")
509 ; CHECK-NEXT: ret float [[RET]]
511 %ret = call nnan float @llvm.experimental.constrained.fsub.f32(float %a, float %a, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
515 ; Missing nnan: must not fire.
516 define float @fsub_x_x_ebstrict(float %a) #0 {
517 ; CHECK-LABEL: @fsub_x_x_ebstrict(
518 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float [[A]], metadata !"round.tonearest", metadata !"fpexcept.strict")
519 ; CHECK-NEXT: ret float [[RET]]
521 %ret = call float @llvm.experimental.constrained.fsub.f32(float %a, float %a, metadata !"round.tonearest", metadata !"fpexcept.strict")
525 ; TODO: This will fold if we allow non-default floating point environments.
526 ; The instruction is expected to remain, but the result isn't used.
527 define float @fsub_nnan_x_x_ebstrict(float %a) #0 {
528 ; CHECK-LABEL: @fsub_nnan_x_x_ebstrict(
529 ; CHECK-NEXT: [[RET:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float [[A]], metadata !"round.tonearest", metadata !"fpexcept.strict")
530 ; CHECK-NEXT: ret float [[RET]]
532 %ret = call nnan float @llvm.experimental.constrained.fsub.f32(float %a, float %a, metadata !"round.tonearest", metadata !"fpexcept.strict")
540 ; Missing nsz and reassoc: must not fire
541 define float @fsub_fsub_y_x_x_defaultenv(float %x, float %y) #0 {
542 ; CHECK-LABEL: @fsub_fsub_y_x_x_defaultenv(
543 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[Y:%.*]], float [[X:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore")
544 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[Y]], float [[INNER]], metadata !"round.tonearest", metadata !"fpexcept.ignore")
545 ; CHECK-NEXT: ret float [[RET]]
547 %inner = call float @llvm.experimental.constrained.fsub.f32(float %y, float %x, metadata !"round.tonearest", metadata !"fpexcept.ignore")
548 %ret = call float @llvm.experimental.constrained.fsub.f32(float %y, float %inner, metadata !"round.tonearest", metadata !"fpexcept.ignore")
552 ; TODO: Need constrained intrinsic support in m_c_FAdd() and m_FSub to fire.
553 define float @fsub_fsub_fmf_y_x_x_defaultenv(float %x, float %y) #0 {
554 ; CHECK-LABEL: @fsub_fsub_fmf_y_x_x_defaultenv(
555 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[Y:%.*]], float [[X:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore")
556 ; CHECK-NEXT: [[RET:%.*]] = call reassoc nsz float @llvm.experimental.constrained.fsub.f32(float [[Y]], float [[INNER]], metadata !"round.tonearest", metadata !"fpexcept.ignore")
557 ; CHECK-NEXT: ret float [[RET]]
559 %inner = call float @llvm.experimental.constrained.fsub.f32(float %y, float %x, metadata !"round.tonearest", metadata !"fpexcept.ignore")
560 %ret = call nsz reassoc float @llvm.experimental.constrained.fsub.f32(float %y, float %inner, metadata !"round.tonearest", metadata !"fpexcept.ignore")
564 ; TODO: Consider how alternate rounding modes can break these transforms.
566 ; The "fpexcept.maytrap" instruction must _not_ be folded into the
567 ; "fpexcept.ignore" instruction. This must not fire.
568 define float @fsub_fsub_fmf_y_x_x_ebmaytrap_defaultenv(float %x, float %y) #0 {
569 ; CHECK-LABEL: @fsub_fsub_fmf_y_x_x_ebmaytrap_defaultenv(
570 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[Y:%.*]], float [[X:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap")
571 ; CHECK-NEXT: [[RET:%.*]] = call reassoc nsz float @llvm.experimental.constrained.fsub.f32(float [[Y]], float [[INNER]], metadata !"round.tonearest", metadata !"fpexcept.ignore")
572 ; CHECK-NEXT: ret float [[RET]]
574 %inner = call float @llvm.experimental.constrained.fsub.f32(float %y, float %x, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
575 %ret = call nsz reassoc float @llvm.experimental.constrained.fsub.f32(float %y, float %inner, metadata !"round.tonearest", metadata !"fpexcept.ignore")
579 ; Missing nsz and reassoc: must not fire
580 define float @fsub_fsub_y_x_x_ebmaytrap(float %x, float %y) #0 {
581 ; CHECK-LABEL: @fsub_fsub_y_x_x_ebmaytrap(
582 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[Y:%.*]], float [[X:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap")
583 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[Y]], float [[INNER]], metadata !"round.tonearest", metadata !"fpexcept.maytrap")
584 ; CHECK-NEXT: ret float [[RET]]
586 %inner = call float @llvm.experimental.constrained.fsub.f32(float %y, float %x, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
587 %ret = call float @llvm.experimental.constrained.fsub.f32(float %y, float %inner, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
591 ; TODO: Need constrained intrinsic support in m_c_FAdd() and m_FSub to fire.
592 define float @fsub_fsub_fmf_y_x_x_ebmaytrap(float %x, float %y) #0 {
593 ; CHECK-LABEL: @fsub_fsub_fmf_y_x_x_ebmaytrap(
594 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[Y:%.*]], float [[X:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap")
595 ; CHECK-NEXT: [[RET:%.*]] = call reassoc nsz float @llvm.experimental.constrained.fsub.f32(float [[Y]], float [[INNER]], metadata !"round.tonearest", metadata !"fpexcept.maytrap")
596 ; CHECK-NEXT: ret float [[RET]]
598 %inner = call float @llvm.experimental.constrained.fsub.f32(float %y, float %x, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
599 %ret = call nsz reassoc float @llvm.experimental.constrained.fsub.f32(float %y, float %inner, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
603 ; Missing nsz and reassoc: must not fire
604 define float @fsub_fsub_y_x_x_ebstrict(float %x, float %y) #0 {
605 ; CHECK-LABEL: @fsub_fsub_y_x_x_ebstrict(
606 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[Y:%.*]], float [[X:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict")
607 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[Y]], float [[INNER]], metadata !"round.tonearest", metadata !"fpexcept.strict")
608 ; CHECK-NEXT: ret float [[RET]]
610 %inner = call float @llvm.experimental.constrained.fsub.f32(float %y, float %x, metadata !"round.tonearest", metadata !"fpexcept.strict")
611 %ret = call float @llvm.experimental.constrained.fsub.f32(float %y, float %inner, metadata !"round.tonearest", metadata !"fpexcept.strict")
615 ; TODO: Need constrained intrinsic support in m_c_FAdd() and m_FSub to fire.
616 define float @fsub_fsub_fmf_y_x_x_ebstrict(float %x, float %y) #0 {
617 ; CHECK-LABEL: @fsub_fsub_fmf_y_x_x_ebstrict(
618 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[Y:%.*]], float [[X:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict")
619 ; CHECK-NEXT: [[RET:%.*]] = call reassoc nsz float @llvm.experimental.constrained.fsub.f32(float [[Y]], float [[INNER]], metadata !"round.tonearest", metadata !"fpexcept.strict")
620 ; CHECK-NEXT: ret float [[RET]]
622 %inner = call float @llvm.experimental.constrained.fsub.f32(float %y, float %x, metadata !"round.tonearest", metadata !"fpexcept.strict")
623 %ret = call nsz reassoc float @llvm.experimental.constrained.fsub.f32(float %y, float %inner, metadata !"round.tonearest", metadata !"fpexcept.strict")
629 ; TODO: Missing IR matcher support means these won't fire.
632 ; Missing nsz and reassoc: must not fire
633 define float @fadd_fsub_x_y_y_defaultenv(float %x, float %y) #0 {
634 ; CHECK-LABEL: @fadd_fsub_x_y_y_defaultenv(
635 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[X:%.*]], float [[Y:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore")
636 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[INNER]], float [[Y]], metadata !"round.tonearest", metadata !"fpexcept.ignore")
637 ; CHECK-NEXT: ret float [[RET]]
639 %inner = call float @llvm.experimental.constrained.fadd.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.ignore")
640 %ret = call float @llvm.experimental.constrained.fsub.f32(float %inner, float %y, metadata !"round.tonearest", metadata !"fpexcept.ignore")
644 ; TODO: Need constrained intrinsic support in m_c_FAdd() and m_FSub to fire.
645 define float @fadd_fsub_fmf_x_y_y_defaultenv(float %x, float %y) #0 {
646 ; CHECK-LABEL: @fadd_fsub_fmf_x_y_y_defaultenv(
647 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[X:%.*]], float [[Y:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore")
648 ; CHECK-NEXT: [[RET:%.*]] = call reassoc nsz float @llvm.experimental.constrained.fsub.f32(float [[INNER]], float [[Y]], metadata !"round.tonearest", metadata !"fpexcept.ignore")
649 ; CHECK-NEXT: ret float [[RET]]
651 %inner = call float @llvm.experimental.constrained.fadd.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.ignore")
652 %ret = call nsz reassoc float @llvm.experimental.constrained.fsub.f32(float %inner, float %y, metadata !"round.tonearest", metadata !"fpexcept.ignore")
656 ; The "fpexcept.maytrap" instruction must _not_ be folded into the
657 ; "fpexcept.ignore" instruction. This must not fire.
658 define float @fadd_fsub_fmf_x_y_y_ebmaytrap_defaultenv(float %x, float %y) #0 {
659 ; CHECK-LABEL: @fadd_fsub_fmf_x_y_y_ebmaytrap_defaultenv(
660 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[X:%.*]], float [[Y:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap")
661 ; CHECK-NEXT: [[RET:%.*]] = call reassoc nsz float @llvm.experimental.constrained.fsub.f32(float [[INNER]], float [[Y]], metadata !"round.tonearest", metadata !"fpexcept.ignore")
662 ; CHECK-NEXT: ret float [[RET]]
664 %inner = call float @llvm.experimental.constrained.fadd.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
665 %ret = call nsz reassoc float @llvm.experimental.constrained.fsub.f32(float %inner, float %y, metadata !"round.tonearest", metadata !"fpexcept.ignore")
669 ; Missing nsz and reassoc: must not fire
670 define float @fadd_fsub_x_y_y_ebmaytrap(float %x, float %y) #0 {
671 ; CHECK-LABEL: @fadd_fsub_x_y_y_ebmaytrap(
672 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[X:%.*]], float [[Y:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap")
673 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[INNER]], float [[Y]], metadata !"round.tonearest", metadata !"fpexcept.maytrap")
674 ; CHECK-NEXT: ret float [[RET]]
676 %inner = call float @llvm.experimental.constrained.fadd.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
677 %ret = call float @llvm.experimental.constrained.fsub.f32(float %inner, float %y, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
681 ; TODO: Need constrained intrinsic support in m_c_FAdd() and m_FSub to fire.
682 define float @fadd_fsub_fmf_x_y_y_ebmaytrap(float %x, float %y) #0 {
683 ; CHECK-LABEL: @fadd_fsub_fmf_x_y_y_ebmaytrap(
684 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[X:%.*]], float [[Y:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap")
685 ; CHECK-NEXT: [[RET:%.*]] = call reassoc nsz float @llvm.experimental.constrained.fsub.f32(float [[INNER]], float [[Y]], metadata !"round.tonearest", metadata !"fpexcept.maytrap")
686 ; CHECK-NEXT: ret float [[RET]]
688 %inner = call float @llvm.experimental.constrained.fadd.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
689 %ret = call nsz reassoc float @llvm.experimental.constrained.fsub.f32(float %inner, float %y, metadata !"round.tonearest", metadata !"fpexcept.maytrap")
693 ; Missing nsz and reassoc: must not fire
694 define float @fadd_fsub_x_y_y_ebstrict(float %x, float %y) #0 {
695 ; CHECK-LABEL: @fadd_fsub_x_y_y_ebstrict(
696 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[X:%.*]], float [[Y:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict")
697 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[INNER]], float [[Y]], metadata !"round.tonearest", metadata !"fpexcept.strict")
698 ; CHECK-NEXT: ret float [[RET]]
700 %inner = call float @llvm.experimental.constrained.fadd.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.strict")
701 %ret = call float @llvm.experimental.constrained.fsub.f32(float %inner, float %y, metadata !"round.tonearest", metadata !"fpexcept.strict")
705 ; TODO: Need constrained intrinsic support in m_c_FAdd() and m_FSub to fire.
706 define float @fadd_fsub_fmf_x_y_y_ebstrict(float %x, float %y) #0 {
707 ; CHECK-LABEL: @fadd_fsub_fmf_x_y_y_ebstrict(
708 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[X:%.*]], float [[Y:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict")
709 ; CHECK-NEXT: [[RET:%.*]] = call reassoc nsz float @llvm.experimental.constrained.fsub.f32(float [[INNER]], float [[Y]], metadata !"round.tonearest", metadata !"fpexcept.strict")
710 ; CHECK-NEXT: ret float [[RET]]
712 %inner = call float @llvm.experimental.constrained.fadd.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.strict")
713 %ret = call nsz reassoc float @llvm.experimental.constrained.fsub.f32(float %inner, float %y, metadata !"round.tonearest", metadata !"fpexcept.strict")
717 declare float @llvm.fabs.f32(float)
718 declare <2 x float> @llvm.fabs.v2f32(<2 x float>)
720 declare float @llvm.experimental.constrained.fadd.f32(float, float, metadata, metadata)
721 declare float @llvm.experimental.constrained.fsub.f32(float, float, metadata, metadata)
723 declare float @llvm.experimental.constrained.sitofp.f32.i32(i32, metadata, metadata)
725 attributes #0 = { strictfp }