[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / test / Transforms / InstSimplify / strictfp-fsub.ll
blob5db531054491864d12e1c08142cb8fee1f81b292
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instsimplify -S | FileCheck %s
5 ; constrained fsub
9 ; fsub X, +0 ==> X
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
17   ret float %ret
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
27   ret float %ret
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
37   ret float %ret
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
47   ret float %ret
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
58   ret float %ret
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
68   ret float %ret
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
81   ret float %sub
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
91   ret float %sub
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
101   ret float %sub
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
111   ret float %sub
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
122   ret float %sub
126 ; fsub X, -0 ==> X, when we know X is not -0
127 ; (No "nsz" flags)
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
137   ret float %sub
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
149   ret float %sub
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
161   ret float %sub
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
173   ret float %sub
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
186   ret float %sub
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
198   ret float %sub
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
211   ret float %ret
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
223   ret float %ret
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
235   ret float %ret
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
247   ret float %ret
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
260   ret float %ret
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
276   ret float %ret
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
288   ret float %ret
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
300   ret float %ret
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
312   ret float %ret
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
324   ret float %ret
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
337   ret float %ret
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
349   ret float %ret
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
361   ret float %ret
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
373   ret float %ret
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
386   ret float %ret
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
402   ret float %ret
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
414   ret float %ret
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
426   ret float %ret
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
438   ret float %ret
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
450   ret float %ret
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
464   ret float %ret
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
472   ret float %ret
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
482   ret float %ret
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
492   ret float %ret
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
502   ret float %ret
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
513   ret float %ret
517 ; Y - (Y - X) --> X
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
529   ret float %ret
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
541   ret float %ret
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
556   ret float %ret
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
568   ret float %ret
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
580   ret float %ret
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
592   ret float %ret
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
604   ret float %ret
608 ; (X + Y) - Y --> X
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
621   ret float %ret
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
633   ret float %ret
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
646   ret float %ret
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
658   ret float %ret
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
670   ret float %ret
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
682   ret float %ret
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
694   ret float %ret
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 }