1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -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") #0
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") #[[ATTR0:[0-9]+]]
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") #0
30 ; TODO: This will fold if we allow non-default floating point environments.
31 define float @fsub_nnan_x_p0_ebmaytrap(float %a) #0 {
32 ; CHECK-LABEL: @fsub_nnan_x_p0_ebmaytrap(
33 ; CHECK-NEXT: [[RET:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float 0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
34 ; CHECK-NEXT: ret float [[RET]]
36 %ret = call nnan float @llvm.experimental.constrained.fsub.f32(float %a, float 0.0, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
40 ; Missing nnan: must not fire.
41 define float @fsub_x_p0_ebstrict(float %a) #0 {
42 ; CHECK-LABEL: @fsub_x_p0_ebstrict(
43 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float 0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
44 ; CHECK-NEXT: ret float [[RET]]
46 %ret = call float @llvm.experimental.constrained.fsub.f32(float %a, float 0.0, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
50 ; TODO: This will fold if we allow non-default floating point environments.
51 ; TODO: The instruction is expected to remain, but the result isn't used.
52 define float @fsub_nnan_x_p0_ebstrict(float %a) #0 {
53 ; CHECK-LABEL: @fsub_nnan_x_p0_ebstrict(
54 ; CHECK-NEXT: [[RET:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float 0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
55 ; CHECK-NEXT: ret float [[RET]]
57 %ret = call nnan float @llvm.experimental.constrained.fsub.f32(float %a, float 0.0, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
61 ; Test with a fast math flag set but that flag is not "nnan".
62 define float @fsub_ninf_x_p0_ebstrict(float %a) #0 {
63 ; CHECK-LABEL: @fsub_ninf_x_p0_ebstrict(
64 ; CHECK-NEXT: [[RET:%.*]] = call ninf float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float 0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
65 ; CHECK-NEXT: ret float [[RET]]
67 %ret = call ninf float @llvm.experimental.constrained.fsub.f32(float %a, float 0.0, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
72 ; fsub X, -0 ==> X, when we know X is not -0
73 ; (fast math flag: nsz)
76 define float @fold_fsub_nsz_x_n0_defaultenv(float %a) #0 {
77 ; CHECK-LABEL: @fold_fsub_nsz_x_n0_defaultenv(
78 ; CHECK-NEXT: ret float [[A:%.*]]
80 %sub = call nsz float @llvm.experimental.constrained.fsub.f32(float %a, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
84 ; Missing nnan: must not fire.
85 define float @fold_fsub_nsz_x_n0_ebmaytrap(float %a) #0 {
86 ; CHECK-LABEL: @fold_fsub_nsz_x_n0_ebmaytrap(
87 ; CHECK-NEXT: [[SUB:%.*]] = call nsz float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float -0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
88 ; CHECK-NEXT: ret float [[SUB]]
90 %sub = call nsz float @llvm.experimental.constrained.fsub.f32(float %a, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
94 ; TODO: This will fold if we allow non-default floating point environments.
95 define float @fold_fsub_nnan_nsz_x_n0_ebmaytrap(float %a) #0 {
96 ; CHECK-LABEL: @fold_fsub_nnan_nsz_x_n0_ebmaytrap(
97 ; CHECK-NEXT: [[SUB:%.*]] = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float -0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
98 ; CHECK-NEXT: ret float [[SUB]]
100 %sub = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float %a, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
104 ; Missing nnan: must not fire.
105 define float @fold_fsub_nsz_x_n0_ebstrict(float %a) #0 {
106 ; CHECK-LABEL: @fold_fsub_nsz_x_n0_ebstrict(
107 ; CHECK-NEXT: [[SUB:%.*]] = call nsz float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float -0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
108 ; CHECK-NEXT: ret float [[SUB]]
110 %sub = call nsz float @llvm.experimental.constrained.fsub.f32(float %a, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
114 ; TODO: This will fold if we allow non-default floating point environments.
115 ; TODO: The instruction is expected to remain, but the result isn't used.
116 define float @fold_fsub_nsz_nnan_x_n0_ebstrict(float %a) #0 {
117 ; CHECK-LABEL: @fold_fsub_nsz_nnan_x_n0_ebstrict(
118 ; CHECK-NEXT: [[SUB:%.*]] = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float -0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
119 ; CHECK-NEXT: ret float [[SUB]]
121 %sub = call nsz nnan float @llvm.experimental.constrained.fsub.f32(float %a, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
126 ; fsub X, -0 ==> X, when we know X is not -0
130 define float @fold_fsub_fabs_x_n0_defaultenv(float %a) #0 {
131 ; CHECK-LABEL: @fold_fsub_fabs_x_n0_defaultenv(
132 ; CHECK-NEXT: [[ABSA:%.*]] = call float @llvm.fabs.f32(float [[A:%.*]])
133 ; CHECK-NEXT: ret float [[ABSA]]
135 %absa = call float @llvm.fabs.f32(float %a)
136 %sub = call float @llvm.experimental.constrained.fsub.f32(float %absa, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
140 ; Missing nnan: must not fire.
141 define float @fold_fsub_fabs_x_n0_ebmaytrap(float %a) #0 {
142 ; CHECK-LABEL: @fold_fsub_fabs_x_n0_ebmaytrap(
143 ; CHECK-NEXT: [[ABSA:%.*]] = call float @llvm.fabs.f32(float [[A:%.*]])
144 ; CHECK-NEXT: [[SUB:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[ABSA]], float -0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
145 ; CHECK-NEXT: ret float [[SUB]]
147 %absa = call float @llvm.fabs.f32(float %a)
148 %sub = call float @llvm.experimental.constrained.fsub.f32(float %absa, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
152 ; TODO: This will fold if we allow non-default floating point environments.
153 define float @fold_fsub_fabs_nnan_x_n0_ebmaytrap(float %a) #0 {
154 ; CHECK-LABEL: @fold_fsub_fabs_nnan_x_n0_ebmaytrap(
155 ; CHECK-NEXT: [[ABSA:%.*]] = call float @llvm.fabs.f32(float [[A:%.*]])
156 ; CHECK-NEXT: [[SUB:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float [[ABSA]], float -0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
157 ; CHECK-NEXT: ret float [[SUB]]
159 %absa = call float @llvm.fabs.f32(float %a)
160 %sub = call nnan float @llvm.experimental.constrained.fsub.f32(float %absa, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
164 ; Missing nnan: must not fire.
165 define float @fold_fsub_fabs_x_n0_ebstrict(float %a) #0 {
166 ; CHECK-LABEL: @fold_fsub_fabs_x_n0_ebstrict(
167 ; CHECK-NEXT: [[ABSA:%.*]] = call float @llvm.fabs.f32(float [[A:%.*]])
168 ; CHECK-NEXT: [[SUB:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[ABSA]], float -0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
169 ; CHECK-NEXT: ret float [[SUB]]
171 %absa = call float @llvm.fabs.f32(float %a)
172 %sub = call float @llvm.experimental.constrained.fsub.f32(float %absa, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
176 ; TODO: This will fold if we allow non-default floating point environments.
177 ; TODO: The instruction is expected to remain, but the result isn't used.
178 define float @fold_fsub_fabs_nnan_x_n0_ebstrict(float %a) #0 {
179 ; CHECK-LABEL: @fold_fsub_fabs_nnan_x_n0_ebstrict(
180 ; CHECK-NEXT: [[ABSA:%.*]] = call float @llvm.fabs.f32(float [[A:%.*]])
181 ; CHECK-NEXT: [[SUB:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float [[ABSA]], float -0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
182 ; CHECK-NEXT: ret float [[SUB]]
184 %absa = call float @llvm.fabs.f32(float %a)
185 %sub = call nnan float @llvm.experimental.constrained.fsub.f32(float %absa, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
189 ; TODO: This can't fire currently due to missing constrained support:
190 define float @fold_fsub_sitofp_x_n0_defaultenv(i32 %a) #0 {
191 ; CHECK-LABEL: @fold_fsub_sitofp_x_n0_defaultenv(
192 ; CHECK-NEXT: [[FPA:%.*]] = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
193 ; CHECK-NEXT: [[SUB:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[FPA]], float -0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
194 ; CHECK-NEXT: ret float [[SUB]]
196 %fpa = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
197 %sub = call float @llvm.experimental.constrained.fsub.f32(float %fpa, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
202 ; fsub -0.0, (fneg X) ==> X
205 define float @fsub_fneg_n0_fnX_defaultenv(float %a) #0 {
206 ; CHECK-LABEL: @fsub_fneg_n0_fnX_defaultenv(
207 ; CHECK-NEXT: ret float [[A:%.*]]
209 %nega = fneg float %a
210 %ret = call float @llvm.experimental.constrained.fsub.f32(float -0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
214 ; Missing nnan: must not fire.
215 define float @fsub_fneg_n0_fnX_ebmaytrap(float %a) #0 {
216 ; CHECK-LABEL: @fsub_fneg_n0_fnX_ebmaytrap(
217 ; CHECK-NEXT: [[NEGA:%.*]] = fneg float [[A:%.*]]
218 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
219 ; CHECK-NEXT: ret float [[RET]]
221 %nega = fneg float %a
222 %ret = call float @llvm.experimental.constrained.fsub.f32(float -0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
226 ; TODO: This will fold if we allow non-default floating point environments.
227 define float @fsub_fneg_nnan_n0_fnX_ebmaytrap(float %a) #0 {
228 ; CHECK-LABEL: @fsub_fneg_nnan_n0_fnX_ebmaytrap(
229 ; CHECK-NEXT: [[NEGA:%.*]] = fneg float [[A:%.*]]
230 ; CHECK-NEXT: [[RET:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
231 ; CHECK-NEXT: ret float [[RET]]
233 %nega = fneg float %a
234 %ret = call nnan float @llvm.experimental.constrained.fsub.f32(float -0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
238 ; Missing nnan: must not fire.
239 define float @fsub_fneg_n0_fnX_ebstrict(float %a) #0 {
240 ; CHECK-LABEL: @fsub_fneg_n0_fnX_ebstrict(
241 ; CHECK-NEXT: [[NEGA:%.*]] = fneg float [[A:%.*]]
242 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
243 ; CHECK-NEXT: ret float [[RET]]
245 %nega = fneg float %a
246 %ret = call float @llvm.experimental.constrained.fsub.f32(float -0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
250 ; TODO: This will fold if we allow non-default floating point environments.
251 ; TODO: The instruction is expected to remain, but the result isn't used.
252 define float @fsub_fneg_nnan_n0_fnX_ebstrict(float %a) #0 {
253 ; CHECK-LABEL: @fsub_fneg_nnan_n0_fnX_ebstrict(
254 ; CHECK-NEXT: [[NEGA:%.*]] = fneg float [[A:%.*]]
255 ; CHECK-NEXT: [[RET:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
256 ; CHECK-NEXT: ret float [[RET]]
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.strict") #0
264 ; fsub -0.0, (fsub -0.0, X) ==> X
267 ; TODO: This won't fire without m_FNeg() knowing the constrained intrinsics.
268 define float @fsub_fsub_n0_fnX_defaultenv(float %a) #0 {
269 ; CHECK-LABEL: @fsub_fsub_n0_fnX_defaultenv(
270 ; CHECK-NEXT: [[NEGA:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
271 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
272 ; CHECK-NEXT: ret float [[RET]]
274 %nega = call float @llvm.experimental.constrained.fsub.f32(float -0.0, float %a, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
275 %ret = call float @llvm.experimental.constrained.fsub.f32(float -0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
279 ; Missing nnan: must not fire.
280 define float @fsub_fsub_n0_fnX_ebmaytrap(float %a) #0 {
281 ; CHECK-LABEL: @fsub_fsub_n0_fnX_ebmaytrap(
282 ; CHECK-NEXT: [[NEGA:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
283 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
284 ; CHECK-NEXT: ret float [[RET]]
286 %nega = call float @llvm.experimental.constrained.fsub.f32(float -0.0, float %a, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
287 %ret = call float @llvm.experimental.constrained.fsub.f32(float -0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
291 ; TODO: This won't fire without m_FNeg() knowing the constrained intrinsics.
292 define float @fsub_fsub_nnan_n0_fnX_ebmaytrap(float %a) #0 {
293 ; CHECK-LABEL: @fsub_fsub_nnan_n0_fnX_ebmaytrap(
294 ; CHECK-NEXT: [[NEGA:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
295 ; CHECK-NEXT: [[RET:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
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.maytrap") #0
299 %ret = call nnan float @llvm.experimental.constrained.fsub.f32(float -0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
303 ; Missing nnan: must not fire.
304 define float @fsub_fsub_n0_fnX_ebstrict(float %a) #0 {
305 ; CHECK-LABEL: @fsub_fsub_n0_fnX_ebstrict(
306 ; CHECK-NEXT: [[NEGA:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
307 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
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.strict") #0
311 %ret = call float @llvm.experimental.constrained.fsub.f32(float -0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
315 ; TODO: This won't fire without m_FNeg() knowing the constrained intrinsics.
316 define float @fsub_fsub_nnan_n0_fnX_ebstrict(float %a) #0 {
317 ; CHECK-LABEL: @fsub_fsub_nnan_n0_fnX_ebstrict(
318 ; CHECK-NEXT: [[NEGA:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
319 ; CHECK-NEXT: [[RET:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float -0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
320 ; CHECK-NEXT: ret float [[RET]]
322 %nega = call nnan float @llvm.experimental.constrained.fsub.f32(float -0.0, float %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
323 %ret = call nnan float @llvm.experimental.constrained.fsub.f32(float -0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
328 ; fsub 0.0, (fneg X) ==> X if signed zeros are ignored.
331 define float @fsub_fneg_nsz_p0_fnX_defaultenv(float %a) #0 {
332 ; CHECK-LABEL: @fsub_fneg_nsz_p0_fnX_defaultenv(
333 ; CHECK-NEXT: ret float [[A:%.*]]
335 %nega = fneg float %a
336 %ret = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
340 ; Missing nnan: must not fire.
341 define float @fsub_fneg_nsz_p0_fnX_ebmaytrap(float %a) #0 {
342 ; CHECK-LABEL: @fsub_fneg_nsz_p0_fnX_ebmaytrap(
343 ; CHECK-NEXT: [[NEGA:%.*]] = fneg float [[A:%.*]]
344 ; CHECK-NEXT: [[RET:%.*]] = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
345 ; CHECK-NEXT: ret float [[RET]]
347 %nega = fneg float %a
348 %ret = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
352 ; TODO: This will fold if we allow non-default floating point environments.
353 define float @fsub_fneg_nsz_nnan_p0_fnX_ebmaytrap(float %a) #0 {
354 ; CHECK-LABEL: @fsub_fneg_nsz_nnan_p0_fnX_ebmaytrap(
355 ; CHECK-NEXT: [[NEGA:%.*]] = fneg float [[A:%.*]]
356 ; CHECK-NEXT: [[RET:%.*]] = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
357 ; CHECK-NEXT: ret float [[RET]]
359 %nega = fneg float %a
360 %ret = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
364 ; Missing nnan: must not fire.
365 define float @fsub_fneg_nsz_p0_fnX_ebstrict(float %a) #0 {
366 ; CHECK-LABEL: @fsub_fneg_nsz_p0_fnX_ebstrict(
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.strict") #[[ATTR0]]
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.strict") #0
376 ; TODO: This will fold if we allow non-default floating point environments.
377 ; TODO: The instruction is expected to remain, but the result isn't used.
378 define float @fsub_fneg_nnan_nsz_p0_fnX_ebstrict(float %a) #0 {
379 ; CHECK-LABEL: @fsub_fneg_nnan_nsz_p0_fnX_ebstrict(
380 ; CHECK-NEXT: [[NEGA:%.*]] = fneg float [[A:%.*]]
381 ; CHECK-NEXT: [[RET:%.*]] = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
382 ; CHECK-NEXT: ret float [[RET]]
384 %nega = fneg float %a
385 %ret = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
390 ; fsub 0.0, (fsub 0.0, X) ==> X if signed zeros are ignored.
393 ; TODO: Need constrained intrinsic support in m_FNeg() and m_FSub to fire.
394 define float @fsub_fsub_p0_nsz_fnX_defaultenv(float %a) #0 {
395 ; CHECK-LABEL: @fsub_fsub_p0_nsz_fnX_defaultenv(
396 ; CHECK-NEXT: [[NEGA:%.*]] = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
397 ; CHECK-NEXT: [[RET:%.*]] = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
398 ; CHECK-NEXT: ret float [[RET]]
400 %nega = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %a, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
401 %ret = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
405 ; Missing nnan: must not fire.
406 define float @fsub_fsub_nsz_p0_fnX_ebmaytrap(float %a) #0 {
407 ; CHECK-LABEL: @fsub_fsub_nsz_p0_fnX_ebmaytrap(
408 ; CHECK-NEXT: [[NEGA:%.*]] = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
409 ; CHECK-NEXT: [[RET:%.*]] = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
410 ; CHECK-NEXT: ret float [[RET]]
412 %nega = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %a, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
413 %ret = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
417 ; TODO: Need constrained intrinsic support in m_FNeg() and m_FSub to fire.
418 define float @fsub_fsub_nnan_nsz_p0_fnX_ebmaytrap(float %a) #0 {
419 ; CHECK-LABEL: @fsub_fsub_nnan_nsz_p0_fnX_ebmaytrap(
420 ; CHECK-NEXT: [[NEGA:%.*]] = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
421 ; CHECK-NEXT: [[RET:%.*]] = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
422 ; CHECK-NEXT: ret float [[RET]]
424 %nega = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %a, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
425 %ret = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
429 ; Missing nnan: must not fire.
430 define float @fsub_fsub_nsz_p0_fnX_ebstrict(float %a) #0 {
431 ; CHECK-LABEL: @fsub_fsub_nsz_p0_fnX_ebstrict(
432 ; CHECK-NEXT: [[NEGA:%.*]] = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
433 ; CHECK-NEXT: [[RET:%.*]] = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
434 ; CHECK-NEXT: ret float [[RET]]
436 %nega = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
437 %ret = call nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
441 ; TODO: Need constrained intrinsic support in m_FNeg() and m_FSub to fire.
442 define float @fsub_fsub_nnan_nsz_p0_fnX_ebstrict(float %a) #0 {
443 ; CHECK-LABEL: @fsub_fsub_nnan_nsz_p0_fnX_ebstrict(
444 ; CHECK-NEXT: [[NEGA:%.*]] = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
445 ; CHECK-NEXT: [[RET:%.*]] = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.000000e+00, float [[NEGA]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
446 ; CHECK-NEXT: ret float [[RET]]
448 %nega = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
449 %ret = call nnan nsz float @llvm.experimental.constrained.fsub.f32(float 0.0, float %nega, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
454 ; fsub nnan x, x ==> 0.0
457 ; Missing nnan: must not fire.
458 define float @fsub_x_x_defaultenv(float %a) #0 {
459 ; CHECK-LABEL: @fsub_x_x_defaultenv(
460 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float [[A]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
461 ; CHECK-NEXT: ret float [[RET]]
463 %ret = call float @llvm.experimental.constrained.fsub.f32(float %a, float %a, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
467 define float @fsub_nnan_x_x_defaultenv(float %a) #0 {
468 ; CHECK-LABEL: @fsub_nnan_x_x_defaultenv(
469 ; CHECK-NEXT: ret float 0.000000e+00
471 %ret = call nnan float @llvm.experimental.constrained.fsub.f32(float %a, float %a, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
475 ; Missing nnan: must not fire.
476 define float @fsub_x_x_ebmaytrap(float %a) #0 {
477 ; CHECK-LABEL: @fsub_x_x_ebmaytrap(
478 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float [[A]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
479 ; CHECK-NEXT: ret float [[RET]]
481 %ret = call float @llvm.experimental.constrained.fsub.f32(float %a, float %a, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
485 ; TODO: This will fold if we allow non-default floating point environments.
486 define float @fsub_nnan_x_x_ebmaytrap(float %a) #0 {
487 ; CHECK-LABEL: @fsub_nnan_x_x_ebmaytrap(
488 ; CHECK-NEXT: [[RET:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float [[A]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
489 ; CHECK-NEXT: ret float [[RET]]
491 %ret = call nnan float @llvm.experimental.constrained.fsub.f32(float %a, float %a, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
495 ; Missing nnan: must not fire.
496 define float @fsub_x_x_ebstrict(float %a) #0 {
497 ; CHECK-LABEL: @fsub_x_x_ebstrict(
498 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float [[A]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
499 ; CHECK-NEXT: ret float [[RET]]
501 %ret = call float @llvm.experimental.constrained.fsub.f32(float %a, float %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
505 ; TODO: This will fold if we allow non-default floating point environments.
506 ; TODO: The instruction is expected to remain, but the result isn't used.
507 define float @fsub_nnan_x_x_ebstrict(float %a) #0 {
508 ; CHECK-LABEL: @fsub_nnan_x_x_ebstrict(
509 ; CHECK-NEXT: [[RET:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float [[A:%.*]], float [[A]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
510 ; CHECK-NEXT: ret float [[RET]]
512 %ret = call nnan float @llvm.experimental.constrained.fsub.f32(float %a, float %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
520 ; Missing nsz and reassoc: must not fire
521 define float @fsub_fsub_y_x_x_defaultenv(float %x, float %y) #0 {
522 ; CHECK-LABEL: @fsub_fsub_y_x_x_defaultenv(
523 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[Y:%.*]], float [[X:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
524 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[Y]], float [[INNER]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
525 ; CHECK-NEXT: ret float [[RET]]
527 %inner = call float @llvm.experimental.constrained.fsub.f32(float %y, float %x, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
528 %ret = call float @llvm.experimental.constrained.fsub.f32(float %y, float %inner, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
532 ; TODO: Need constrained intrinsic support in m_c_FAdd() and m_FSub to fire.
533 define float @fsub_fsub_fmf_y_x_x_defaultenv(float %x, float %y) #0 {
534 ; CHECK-LABEL: @fsub_fsub_fmf_y_x_x_defaultenv(
535 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[Y:%.*]], float [[X:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
536 ; CHECK-NEXT: [[RET:%.*]] = call reassoc nsz float @llvm.experimental.constrained.fsub.f32(float [[Y]], float [[INNER]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
537 ; CHECK-NEXT: ret float [[RET]]
539 %inner = call float @llvm.experimental.constrained.fsub.f32(float %y, float %x, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
540 %ret = call nsz reassoc float @llvm.experimental.constrained.fsub.f32(float %y, float %inner, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
544 ; TODO: Consider how alternate rounding modes can break these transforms.
546 ; The "fpexcept.maytrap" instruction must _not_ be folded into the
547 ; "fpexcept.ignore" instruction. This must not fire.
548 define float @fsub_fsub_fmf_y_x_x_ebmaytrap_defaultenv(float %x, float %y) #0 {
549 ; CHECK-LABEL: @fsub_fsub_fmf_y_x_x_ebmaytrap_defaultenv(
550 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[Y:%.*]], float [[X:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
551 ; CHECK-NEXT: [[RET:%.*]] = call reassoc nsz float @llvm.experimental.constrained.fsub.f32(float [[Y]], float [[INNER]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
552 ; CHECK-NEXT: ret float [[RET]]
554 %inner = call float @llvm.experimental.constrained.fsub.f32(float %y, float %x, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
555 %ret = call nsz reassoc float @llvm.experimental.constrained.fsub.f32(float %y, float %inner, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
559 ; Missing nsz and reassoc: must not fire
560 define float @fsub_fsub_y_x_x_ebmaytrap(float %x, float %y) #0 {
561 ; CHECK-LABEL: @fsub_fsub_y_x_x_ebmaytrap(
562 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[Y:%.*]], float [[X:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
563 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[Y]], float [[INNER]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
564 ; CHECK-NEXT: ret float [[RET]]
566 %inner = call float @llvm.experimental.constrained.fsub.f32(float %y, float %x, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
567 %ret = call float @llvm.experimental.constrained.fsub.f32(float %y, float %inner, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
571 ; TODO: Need constrained intrinsic support in m_c_FAdd() and m_FSub to fire.
572 define float @fsub_fsub_fmf_y_x_x_ebmaytrap(float %x, float %y) #0 {
573 ; CHECK-LABEL: @fsub_fsub_fmf_y_x_x_ebmaytrap(
574 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[Y:%.*]], float [[X:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
575 ; CHECK-NEXT: [[RET:%.*]] = call reassoc nsz float @llvm.experimental.constrained.fsub.f32(float [[Y]], float [[INNER]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
576 ; CHECK-NEXT: ret float [[RET]]
578 %inner = call float @llvm.experimental.constrained.fsub.f32(float %y, float %x, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
579 %ret = call nsz reassoc float @llvm.experimental.constrained.fsub.f32(float %y, float %inner, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
583 ; Missing nsz and reassoc: must not fire
584 define float @fsub_fsub_y_x_x_ebstrict(float %x, float %y) #0 {
585 ; CHECK-LABEL: @fsub_fsub_y_x_x_ebstrict(
586 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[Y:%.*]], float [[X:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
587 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[Y]], float [[INNER]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
588 ; CHECK-NEXT: ret float [[RET]]
590 %inner = call float @llvm.experimental.constrained.fsub.f32(float %y, float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
591 %ret = call float @llvm.experimental.constrained.fsub.f32(float %y, float %inner, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
595 ; TODO: Need constrained intrinsic support in m_c_FAdd() and m_FSub to fire.
596 define float @fsub_fsub_fmf_y_x_x_ebstrict(float %x, float %y) #0 {
597 ; CHECK-LABEL: @fsub_fsub_fmf_y_x_x_ebstrict(
598 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[Y:%.*]], float [[X:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
599 ; CHECK-NEXT: [[RET:%.*]] = call reassoc nsz float @llvm.experimental.constrained.fsub.f32(float [[Y]], float [[INNER]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
600 ; CHECK-NEXT: ret float [[RET]]
602 %inner = call float @llvm.experimental.constrained.fsub.f32(float %y, float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
603 %ret = call nsz reassoc float @llvm.experimental.constrained.fsub.f32(float %y, float %inner, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
609 ; TODO: Missing IR matcher support means these won't fire.
612 ; Missing nsz and reassoc: must not fire
613 define float @fadd_fsub_x_y_y_defaultenv(float %x, float %y) #0 {
614 ; CHECK-LABEL: @fadd_fsub_x_y_y_defaultenv(
615 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[X:%.*]], float [[Y:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
616 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[INNER]], float [[Y]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
617 ; CHECK-NEXT: ret float [[RET]]
619 %inner = call float @llvm.experimental.constrained.fadd.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
620 %ret = call float @llvm.experimental.constrained.fsub.f32(float %inner, float %y, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
624 ; TODO: Need constrained intrinsic support in m_c_FAdd() and m_FSub to fire.
625 define float @fadd_fsub_fmf_x_y_y_defaultenv(float %x, float %y) #0 {
626 ; CHECK-LABEL: @fadd_fsub_fmf_x_y_y_defaultenv(
627 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[X:%.*]], float [[Y:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
628 ; CHECK-NEXT: [[RET:%.*]] = call reassoc nsz float @llvm.experimental.constrained.fsub.f32(float [[INNER]], float [[Y]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
629 ; CHECK-NEXT: ret float [[RET]]
631 %inner = call float @llvm.experimental.constrained.fadd.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
632 %ret = call nsz reassoc float @llvm.experimental.constrained.fsub.f32(float %inner, float %y, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
636 ; The "fpexcept.maytrap" instruction must _not_ be folded into the
637 ; "fpexcept.ignore" instruction. This must not fire.
638 define float @fadd_fsub_fmf_x_y_y_ebmaytrap_defaultenv(float %x, float %y) #0 {
639 ; CHECK-LABEL: @fadd_fsub_fmf_x_y_y_ebmaytrap_defaultenv(
640 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[X:%.*]], float [[Y:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
641 ; CHECK-NEXT: [[RET:%.*]] = call reassoc nsz float @llvm.experimental.constrained.fsub.f32(float [[INNER]], float [[Y]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
642 ; CHECK-NEXT: ret float [[RET]]
644 %inner = call float @llvm.experimental.constrained.fadd.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
645 %ret = call nsz reassoc float @llvm.experimental.constrained.fsub.f32(float %inner, float %y, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
649 ; Missing nsz and reassoc: must not fire
650 define float @fadd_fsub_x_y_y_ebmaytrap(float %x, float %y) #0 {
651 ; CHECK-LABEL: @fadd_fsub_x_y_y_ebmaytrap(
652 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[X:%.*]], float [[Y:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
653 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[INNER]], float [[Y]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
654 ; CHECK-NEXT: ret float [[RET]]
656 %inner = call float @llvm.experimental.constrained.fadd.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
657 %ret = call float @llvm.experimental.constrained.fsub.f32(float %inner, float %y, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
661 ; TODO: Need constrained intrinsic support in m_c_FAdd() and m_FSub to fire.
662 define float @fadd_fsub_fmf_x_y_y_ebmaytrap(float %x, float %y) #0 {
663 ; CHECK-LABEL: @fadd_fsub_fmf_x_y_y_ebmaytrap(
664 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[X:%.*]], float [[Y:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
665 ; CHECK-NEXT: [[RET:%.*]] = call reassoc nsz float @llvm.experimental.constrained.fsub.f32(float [[INNER]], float [[Y]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
666 ; CHECK-NEXT: ret float [[RET]]
668 %inner = call float @llvm.experimental.constrained.fadd.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
669 %ret = call nsz reassoc float @llvm.experimental.constrained.fsub.f32(float %inner, float %y, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
673 ; Missing nsz and reassoc: must not fire
674 define float @fadd_fsub_x_y_y_ebstrict(float %x, float %y) #0 {
675 ; CHECK-LABEL: @fadd_fsub_x_y_y_ebstrict(
676 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[X:%.*]], float [[Y:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
677 ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.experimental.constrained.fsub.f32(float [[INNER]], float [[Y]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
678 ; CHECK-NEXT: ret float [[RET]]
680 %inner = call float @llvm.experimental.constrained.fadd.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
681 %ret = call float @llvm.experimental.constrained.fsub.f32(float %inner, float %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
685 ; TODO: Need constrained intrinsic support in m_c_FAdd() and m_FSub to fire.
686 define float @fadd_fsub_fmf_x_y_y_ebstrict(float %x, float %y) #0 {
687 ; CHECK-LABEL: @fadd_fsub_fmf_x_y_y_ebstrict(
688 ; CHECK-NEXT: [[INNER:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[X:%.*]], float [[Y:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
689 ; CHECK-NEXT: [[RET:%.*]] = call reassoc nsz float @llvm.experimental.constrained.fsub.f32(float [[INNER]], float [[Y]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
690 ; CHECK-NEXT: ret float [[RET]]
692 %inner = call float @llvm.experimental.constrained.fadd.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
693 %ret = call nsz reassoc float @llvm.experimental.constrained.fsub.f32(float %inner, float %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
697 declare float @llvm.fabs.f32(float)
698 declare <2 x float> @llvm.fabs.v2f32(<2 x float>)
700 declare float @llvm.experimental.constrained.fadd.f32(float, float, metadata, metadata) #0
701 declare float @llvm.experimental.constrained.fsub.f32(float, float, metadata, metadata) #0
703 declare float @llvm.experimental.constrained.sitofp.f32.i32(i32, metadata, metadata) #0
705 attributes #0 = { strictfp }