[ConstraintElim] Add support for decomposing gep nuw (#118639)
[llvm-project.git] / llvm / test / Transforms / Attributor / nofpclass.ll
blobb97454a29d513589448621827a01c9c7317caefb
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --version 2
2 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-annotate-decl-cs  -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
3 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
5 declare nofpclass(nan) float @ret_nofpclass_nan()
6 declare [2 x [3 x float]] @ret_array()
7 declare float @extern()
8 declare float @extern.f32(float)
9 declare void @extern.use(float)
10 declare void @extern.use.array([2 x [3 x float]])
11 declare void @llvm.assume(i1 noundef)
12 declare void @unknown()
13 declare half @llvm.fabs.f16(half)
14 declare float @llvm.fabs.f32(float)
15 declare void @extern.use.f16(half)
16 declare i1 @llvm.is.fpclass.f32(float, i32 immarg)
17 declare float @llvm.experimental.constrained.sitofp.f32.i32(i32, metadata, metadata)
18 declare float @llvm.experimental.constrained.uitofp.f32.i32(i32, metadata, metadata)
19 declare float @llvm.arithmetic.fence.f32(float)
21 define float @returned_0() {
22 ; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub norm) float @returned_0() {
23 ; CHECK-NEXT:    call void @unknown()
24 ; CHECK-NEXT:    ret float 0.000000e+00
26   call void @unknown()
27   ret float 0.0
30 define float @returned_neg0() {
31 ; CHECK-LABEL: define noundef nofpclass(nan inf pzero sub norm) float @returned_neg0() {
32 ; CHECK-NEXT:    call void @unknown()
33 ; CHECK-NEXT:    ret float -0.000000e+00
35   call void @unknown()
36   ret float -0.0
39 define float @returned_undef() {
40 ; CHECK-LABEL: define nofpclass(all) float @returned_undef() {
41 ; CHECK-NEXT:    call void @unknown()
42 ; CHECK-NEXT:    ret float undef
44   call void @unknown()
45   ret float undef
48 define float @returned_poison() {
49 ; CHECK-LABEL: define nofpclass(all) float @returned_poison() {
50 ; CHECK-NEXT:    call void @unknown()
51 ; CHECK-NEXT:    ret float poison
53   call void @unknown()
54   ret float poison
57 ; Know nothing
58 define float @returned_freeze_poison() {
59 ; CHECK-LABEL: define noundef float @returned_freeze_poison() {
60 ; CHECK-NEXT:    call void @unknown()
61 ; CHECK-NEXT:    [[FREEZE_POISON:%.*]] = freeze float poison
62 ; CHECK-NEXT:    ret float [[FREEZE_POISON]]
64   call void @unknown()
65   %freeze.poison = freeze float poison
66   ret float %freeze.poison
69 define double @returned_snan() {
70 ; CHECK-LABEL: define noundef nofpclass(qnan inf zero sub norm) double @returned_snan() {
71 ; CHECK-NEXT:    call void @unknown()
72 ; CHECK-NEXT:    ret double 0x7FF0000000000001
74   call void @unknown()
75   ret double 0x7FF0000000000001
78 define double @returned_qnan() {
79 ; CHECK-LABEL: define noundef nofpclass(snan inf zero sub norm) double @returned_qnan() {
80 ; CHECK-NEXT:    call void @unknown()
81 ; CHECK-NEXT:    ret double 0x7FF8000000000000
83   call void @unknown()
84   ret double 0x7FF8000000000000
87 define <2 x double> @returned_zero_vector() {
88 ; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub norm) <2 x double> @returned_zero_vector() {
89 ; CHECK-NEXT:    call void @unknown()
90 ; CHECK-NEXT:    ret <2 x double> zeroinitializer
92   call void @unknown()
93   ret <2 x double> zeroinitializer
96 define <2 x double> @returned_negzero_vector() {
97 ; CHECK-LABEL: define noundef nofpclass(nan inf pzero sub norm) <2 x double> @returned_negzero_vector() {
98 ; CHECK-NEXT:    call void @unknown()
99 ; CHECK-NEXT:    ret <2 x double> splat (double -0.000000e+00)
101   call void @unknown()
102   ret <2 x double> <double -0.0, double -0.0>
105 ; Test a vector element that's a constant but not ConstantFP.
106 define <2 x double> @returned_strange_constant_vector_elt() {
107 ; CHECK-LABEL: define <2 x double> @returned_strange_constant_vector_elt() {
108 ; CHECK-NEXT:    call void @unknown()
109 ; CHECK-NEXT:    ret <2 x double> <double -0.000000e+00, double bitcast (i64 ptrtoint (ptr @unknown to i64) to double)>
111   call void @unknown()
112   ret <2 x double> <double -0.0, double bitcast (i64 ptrtoint (ptr @unknown to i64) to double)>
115 ; Test a vector element that's undef
116 define <3 x double> @returned_undef_constant_vector_elt() {
117 ; CHECK-LABEL: define <3 x double> @returned_undef_constant_vector_elt() {
118 ; CHECK-NEXT:    call void @unknown()
119 ; CHECK-NEXT:    ret <3 x double> <double -0.000000e+00, double 0.000000e+00, double undef>
121   call void @unknown()
122   ret <3 x double> <double -0.0, double 0.0, double undef>
125 ; Test a vector element that's poison
126 define <3 x double> @returned_poison_constant_vector_elt() {
127 ; CHECK-LABEL: define nofpclass(nan inf sub norm) <3 x double> @returned_poison_constant_vector_elt() {
128 ; CHECK-NEXT:    call void @unknown()
129 ; CHECK-NEXT:    ret <3 x double> <double -0.000000e+00, double 0.000000e+00, double poison>
131   call void @unknown()
132   ret <3 x double> <double -0.0, double 0.0, double poison>
135 define <2 x double> @returned_qnan_zero_vector() {
136 ; CHECK-LABEL: define noundef nofpclass(snan inf nzero sub norm) <2 x double> @returned_qnan_zero_vector() {
137 ; CHECK-NEXT:    call void @unknown()
138 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double 0.000000e+00>
140   call void @unknown()
141   ret <2 x double> <double 0x7FF8000000000000, double 0.0>
144 ; Return a float trivially nofpclass(nan) (call return attribute)
145 define float @return_nofpclass_nan_decl_return() {
146 ; CHECK-LABEL: define nofpclass(nan) float @return_nofpclass_nan_decl_return() {
147 ; CHECK-NEXT:    [[RET:%.*]] = call nofpclass(nan) float @ret_nofpclass_nan()
148 ; CHECK-NEXT:    ret float [[RET]]
150   %ret = call float @ret_nofpclass_nan()
151   ret float %ret
154 ; Return a float trivially nofpclass(nan) (argument attribute)
155 define float @return_nofpclass_nan_arg(float returned nofpclass(nan) %p) {
156 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
157 ; CHECK-LABEL: define nofpclass(nan) float @return_nofpclass_nan_arg
158 ; CHECK-SAME: (float returned nofpclass(nan) [[P:%.*]]) #[[ATTR3:[0-9]+]] {
159 ; CHECK-NEXT:    ret float [[P]]
161   ret float %p
164 define [2 x [3 x float]] @return_nofpclass_inf_ret_array() {
165 ; CHECK-LABEL: define nofpclass(inf) [2 x [3 x float]] @return_nofpclass_inf_ret_array() {
166 ; CHECK-NEXT:    [[RET:%.*]] = call nofpclass(inf) [2 x [3 x float]] @ret_array()
167 ; CHECK-NEXT:    ret [2 x [3 x float]] [[RET]]
169   %ret = call nofpclass(inf) [2 x [3 x float]]  @ret_array()
170   ret [2 x [3 x float]] %ret
173 define float @returned_nnan_fadd(float %arg0, float %arg1) {
174 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
175 ; CHECK-LABEL: define nofpclass(nan) float @returned_nnan_fadd
176 ; CHECK-SAME: (float [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR3]] {
177 ; CHECK-NEXT:    [[FADD:%.*]] = fadd nnan float [[ARG0]], [[ARG1]]
178 ; CHECK-NEXT:    ret float [[FADD]]
180   %fadd = fadd nnan float %arg0, %arg1
181   ret float %fadd
184 define float @return_nofpclass_nan_callsite() {
185 ; CHECK-LABEL: define nofpclass(nan) float @return_nofpclass_nan_callsite() {
186 ; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan) float @extern()
187 ; CHECK-NEXT:    ret float [[CALL]]
189   %call = call nofpclass(nan) float @extern()
190   ret float %call
193 ; Can union the return classes
194 define nofpclass(inf) float @return_ninf_nofpclass_nan_callsite() {
195 ; CHECK-LABEL: define nofpclass(nan inf) float @return_ninf_nofpclass_nan_callsite() {
196 ; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan) float @extern()
197 ; CHECK-NEXT:    ret float [[CALL]]
199   %call = call nofpclass(nan) float @extern()
200   ret float %call
203 define void @arg_used_by_nofpclass_nan_callsite(float %arg) {
204 ; CHECK-LABEL: define void @arg_used_by_nofpclass_nan_callsite
205 ; CHECK-SAME: (float nofpclass(nan) [[ARG:%.*]]) {
206 ; CHECK-NEXT:    call void @extern.use(float nofpclass(nan) [[ARG]])
207 ; CHECK-NEXT:    ret void
209   call void @extern.use(float nofpclass(nan) %arg)
210   ret void
213 ; Callsite can union the incoming and outgoing
214 define void @ninf_arg_used_by_nofpclass_nan_callsite(float nofpclass(inf) %arg) {
215 ; CHECK-LABEL: define void @ninf_arg_used_by_nofpclass_nan_callsite
216 ; CHECK-SAME: (float nofpclass(nan inf) [[ARG:%.*]]) {
217 ; CHECK-NEXT:    call void @extern.use(float nofpclass(nan inf) [[ARG]])
218 ; CHECK-NEXT:    ret void
220   call void @extern.use(float nofpclass(nan) %arg)
221   ret void
224 define void @ninf_arg_used_by_callsite_array([2 x [3 x float]] nofpclass(inf) %arg) {
225 ; CHECK-LABEL: define void @ninf_arg_used_by_callsite_array
226 ; CHECK-SAME: ([2 x [3 x float]] nofpclass(inf) [[ARG:%.*]]) {
227 ; CHECK-NEXT:    call void @extern.use.array([2 x [3 x float]] nofpclass(inf) [[ARG]])
228 ; CHECK-NEXT:    ret void
230   call void @extern.use.array([2 x [3 x float]]  %arg)
231   ret void
234 define void @nofpclass_call_use_after_unannotated_use(float %arg) {
235 ; CHECK-LABEL: define void @nofpclass_call_use_after_unannotated_use
236 ; CHECK-SAME: (float nofpclass(nan inf) [[ARG:%.*]]) {
237 ; CHECK-NEXT:    call void @extern(float nofpclass(nan inf) [[ARG]]) #[[ATTR17:[0-9]+]]
238 ; CHECK-NEXT:    call void @extern(float nofpclass(nan inf) [[ARG]])
239 ; CHECK-NEXT:    ret void
241   call void @extern(float %arg) willreturn nounwind ; < annotate this use
242   call void @extern(float nofpclass(nan inf) %arg)
243   ret void
246 define float @mutually_recursive0(float %arg) {
247 ; TUNIT: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
248 ; TUNIT-LABEL: define nofpclass(all) float @mutually_recursive0
249 ; TUNIT-SAME: (float [[ARG:%.*]]) #[[ATTR4:[0-9]+]] {
250 ; TUNIT-NEXT:    ret float undef
252 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
253 ; CGSCC-LABEL: define nofpclass(all) float @mutually_recursive0
254 ; CGSCC-SAME: (float [[ARG:%.*]]) #[[ATTR3]] {
255 ; CGSCC-NEXT:    ret float undef
257   %call = call float @mutually_recursive1(float %arg)
258   ret float %call
261 define float @mutually_recursive1(float %arg) {
262 ; TUNIT: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
263 ; TUNIT-LABEL: define nofpclass(all) float @mutually_recursive1
264 ; TUNIT-SAME: (float [[ARG:%.*]]) #[[ATTR4]] {
265 ; TUNIT-NEXT:    ret float undef
267 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
268 ; CGSCC-LABEL: define nofpclass(all) float @mutually_recursive1
269 ; CGSCC-SAME: (float [[ARG:%.*]]) #[[ATTR3]] {
270 ; CGSCC-NEXT:    ret float undef
272   %call = call float @mutually_recursive0(float %arg)
273   ret float %call
276 define float @recursive_phi(ptr %ptr) {
277 ; CHECK-LABEL: define nofpclass(nan) float @recursive_phi
278 ; CHECK-SAME: (ptr nofree [[PTR:%.*]]) {
279 ; CHECK-NEXT:  entry:
280 ; CHECK-NEXT:    [[RET:%.*]] = call nofpclass(nan) float @ret_nofpclass_nan()
281 ; CHECK-NEXT:    br label [[LOOP:%.*]]
282 ; CHECK:       loop:
283 ; CHECK-NEXT:    [[PHI:%.*]] = phi float [ [[RET]], [[ENTRY:%.*]] ], [ [[RET]], [[LOOP]] ]
284 ; CHECK-NEXT:    [[COND:%.*]] = load volatile i1, ptr [[PTR]], align 1
285 ; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
286 ; CHECK:       exit:
287 ; CHECK-NEXT:    ret float [[RET]]
289 entry:
290   %ret = call float @ret_nofpclass_nan()
291   br label %loop
293 loop:
294   %phi = phi float [%ret, %entry], [%phi, %loop]
295   %cond = load volatile i1, ptr %ptr
296   br i1 %cond, label %loop, label %exit
298 exit:
299   ret float %phi
302 ; Should be able to infer nofpclass(nan) return
303 define float @fcmp_uno_check(float %arg) local_unnamed_addr {
304 ; CHECK-LABEL: define float @fcmp_uno_check
305 ; CHECK-SAME: (float [[ARG:%.*]]) local_unnamed_addr {
306 ; CHECK-NEXT:  entry:
307 ; CHECK-NEXT:    [[ISNAN:%.*]] = fcmp uno float [[ARG]], 0.000000e+00
308 ; CHECK-NEXT:    br i1 [[ISNAN]], label [[BB0:%.*]], label [[BB1:%.*]]
309 ; CHECK:       bb0:
310 ; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan) float @ret_nofpclass_nan()
311 ; CHECK-NEXT:    br label [[BB1]]
312 ; CHECK:       bb1:
313 ; CHECK-NEXT:    [[PHI:%.*]] = phi float [ [[CALL]], [[BB0]] ], [ [[ARG]], [[ENTRY:%.*]] ]
314 ; CHECK-NEXT:    ret float [[PHI]]
316 entry:
317   %isnan = fcmp uno float %arg, 0.0
318   br i1 %isnan, label %bb0, label %bb1
320 bb0:
321   %call = call float @ret_nofpclass_nan()
322   br label %bb1
324 bb1:
325   %phi = phi float [ %call, %bb0 ], [ %arg, %entry ]
326   ret float %phi
329 ; Should be able to infer nofpclass(nan) on %arg use
330 define void @fcmp_ord_guard_callsite_arg(float %arg) {
331 ; CHECK-LABEL: define void @fcmp_ord_guard_callsite_arg
332 ; CHECK-SAME: (float [[ARG:%.*]]) {
333 ; CHECK-NEXT:  entry:
334 ; CHECK-NEXT:    [[IS_NOT_NAN:%.*]] = fcmp ord float [[ARG]], 0.000000e+00
335 ; CHECK-NEXT:    br i1 [[IS_NOT_NAN]], label [[BB0:%.*]], label [[BB1:%.*]]
336 ; CHECK:       bb0:
337 ; CHECK-NEXT:    call void @extern.use(float [[ARG]])
338 ; CHECK-NEXT:    br label [[BB1]]
339 ; CHECK:       bb1:
340 ; CHECK-NEXT:    ret void
342 entry:
343   %is.not.nan = fcmp ord float %arg, 0.0
344   br i1 %is.not.nan, label %bb0, label %bb1
346 bb0:
347   call void @extern.use(float %arg)
348   br label %bb1
350 bb1:
351   ret void
354 ; Should be able to infer nofpclass on both %arg uses
355 define float @fcmp_ord_assume_callsite_arg_return(float %arg) {
356 ; CHECK-LABEL: define float @fcmp_ord_assume_callsite_arg_return
357 ; CHECK-SAME: (float returned [[ARG:%.*]]) {
358 ; CHECK-NEXT:  entry:
359 ; CHECK-NEXT:    [[IS_NOT_NAN:%.*]] = fcmp ord float [[ARG]], 0.000000e+00
360 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_NOT_NAN]]) #[[ATTR18:[0-9]+]]
361 ; CHECK-NEXT:    call void @extern.use(float [[ARG]])
362 ; CHECK-NEXT:    ret float [[ARG]]
364 entry:
365   %is.not.nan = fcmp ord float %arg, 0.0
366   call void @llvm.assume(i1 %is.not.nan)
367   call void @extern.use(float %arg)
368   ret float %arg
371 define internal float @returned_dead() {
372 ; CHECK-LABEL: define internal nofpclass(nan inf nzero sub norm) float @returned_dead() {
373 ; CHECK-NEXT:    call void @unknown()
374 ; CHECK-NEXT:    ret float undef
376   call void @unknown()
377   ret float 0.0
380 define void @returned_dead_caller() {
381 ; CHECK-LABEL: define void @returned_dead_caller() {
382 ; CHECK-NEXT:    [[TMP1:%.*]] = call float @returned_dead()
383 ; CHECK-NEXT:    ret void
385   call float @returned_dead()
386   ret void
389 define internal float @only_nofpclass_inf_callers(float %arg) {
390 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
391 ; CHECK-LABEL: define internal float @only_nofpclass_inf_callers
392 ; CHECK-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR3]] {
393 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
394 ; CHECK-NEXT:    ret float [[ADD]]
396   %add = fadd float %arg, %arg
397   ret float %add
400 define float @call_noinf_0(float nofpclass(inf) %arg) {
401 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
402 ; TUNIT-LABEL: define float @call_noinf_0
403 ; TUNIT-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR3]] {
404 ; TUNIT-NEXT:    [[RESULT:%.*]] = call float @only_nofpclass_inf_callers(float nofpclass(inf) [[ARG]]) #[[ATTR19:[0-9]+]]
405 ; TUNIT-NEXT:    ret float [[RESULT]]
407 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
408 ; CGSCC-LABEL: define float @call_noinf_0
409 ; CGSCC-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR4:[0-9]+]] {
410 ; CGSCC-NEXT:    [[RESULT:%.*]] = call float @only_nofpclass_inf_callers(float nofpclass(inf) [[ARG]]) #[[ATTR19:[0-9]+]]
411 ; CGSCC-NEXT:    ret float [[RESULT]]
413   %result = call float @only_nofpclass_inf_callers(float %arg)
414   ret float %result
417 define float @call_noinf_1(float %arg) {
418 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
419 ; TUNIT-LABEL: define float @call_noinf_1
420 ; TUNIT-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR3]] {
421 ; TUNIT-NEXT:    [[RESULT:%.*]] = call float @only_nofpclass_inf_callers(float nofpclass(inf) [[ARG]]) #[[ATTR19]]
422 ; TUNIT-NEXT:    ret float [[RESULT]]
424 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
425 ; CGSCC-LABEL: define float @call_noinf_1
426 ; CGSCC-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR4]] {
427 ; CGSCC-NEXT:    [[RESULT:%.*]] = call float @only_nofpclass_inf_callers(float nofpclass(inf) [[ARG]]) #[[ATTR19]]
428 ; CGSCC-NEXT:    ret float [[RESULT]]
430   %result = call float @only_nofpclass_inf_callers(float nofpclass(inf) %arg)
431   ret float %result
434 ; TODO: Should be able to infer nofpclass(inf) on return
435 define internal float @only_nofpclass_inf_return_users(float %arg) {
436 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
437 ; CHECK-LABEL: define internal float @only_nofpclass_inf_return_users
438 ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR3]] {
439 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
440 ; CHECK-NEXT:    ret float [[ADD]]
442   %add = fadd float %arg, %arg
443   ret float %add
446 define float @call_noinf_return_0(float %arg) {
447 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
448 ; TUNIT-LABEL: define nofpclass(inf) float @call_noinf_return_0
449 ; TUNIT-SAME: (float [[ARG:%.*]]) #[[ATTR3]] {
450 ; TUNIT-NEXT:    [[RESULT:%.*]] = call nofpclass(inf) float @only_nofpclass_inf_return_users(float [[ARG]]) #[[ATTR19]]
451 ; TUNIT-NEXT:    ret float [[RESULT]]
453 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
454 ; CGSCC-LABEL: define nofpclass(inf) float @call_noinf_return_0
455 ; CGSCC-SAME: (float [[ARG:%.*]]) #[[ATTR4]] {
456 ; CGSCC-NEXT:    [[RESULT:%.*]] = call nofpclass(inf) float @only_nofpclass_inf_return_users(float [[ARG]]) #[[ATTR19]]
457 ; CGSCC-NEXT:    ret float [[RESULT]]
459   %result = call nofpclass(inf) float @only_nofpclass_inf_return_users(float %arg)
460   ret float %result
463 define float @call_noinf_return_1(float %arg) {
464 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
465 ; TUNIT-LABEL: define nofpclass(inf) float @call_noinf_return_1
466 ; TUNIT-SAME: (float [[ARG:%.*]]) #[[ATTR3]] {
467 ; TUNIT-NEXT:    [[RESULT:%.*]] = call nofpclass(inf) float @only_nofpclass_inf_return_users(float [[ARG]]) #[[ATTR19]]
468 ; TUNIT-NEXT:    ret float [[RESULT]]
470 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
471 ; CGSCC-LABEL: define nofpclass(inf) float @call_noinf_return_1
472 ; CGSCC-SAME: (float [[ARG:%.*]]) #[[ATTR4]] {
473 ; CGSCC-NEXT:    [[RESULT:%.*]] = call nofpclass(inf) float @only_nofpclass_inf_return_users(float [[ARG]]) #[[ATTR19]]
474 ; CGSCC-NEXT:    ret float [[RESULT]]
476   %result = call nofpclass(inf) float @only_nofpclass_inf_return_users(float %arg)
477   ret float %result
480 define float @fcmp_olt_assume_one_0_callsite_arg_return(float %arg) {
481 ; CHECK-LABEL: define float @fcmp_olt_assume_one_0_callsite_arg_return
482 ; CHECK-SAME: (float returned [[ARG:%.*]]) {
483 ; CHECK-NEXT:  entry:
484 ; CHECK-NEXT:    [[IS_NOT_ZERO_OR_NAN:%.*]] = fcmp one float [[ARG]], 0.000000e+00
485 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_NOT_ZERO_OR_NAN]]) #[[ATTR18]]
486 ; CHECK-NEXT:    call void @extern.use(float [[ARG]])
487 ; CHECK-NEXT:    ret float [[ARG]]
489 entry:
490   %is.not.zero.or.nan = fcmp one float %arg, 0.0
491   call void @llvm.assume(i1 %is.not.zero.or.nan)
492   call void @extern.use(float %arg)
493   ret float %arg
496 define float @fcmp_olt_assume_une_0_callsite_arg_return(float %arg) {
497 ; CHECK-LABEL: define float @fcmp_olt_assume_une_0_callsite_arg_return
498 ; CHECK-SAME: (float returned [[ARG:%.*]]) {
499 ; CHECK-NEXT:  entry:
500 ; CHECK-NEXT:    [[IS_NOT_ZERO_OR_NAN:%.*]] = fcmp une float [[ARG]], 0.000000e+00
501 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_NOT_ZERO_OR_NAN]]) #[[ATTR18]]
502 ; CHECK-NEXT:    call void @extern.use(float [[ARG]])
503 ; CHECK-NEXT:    ret float [[ARG]]
505 entry:
506   %is.not.zero.or.nan = fcmp une float %arg, 0.0
507   call void @llvm.assume(i1 %is.not.zero.or.nan)
508   call void @extern.use(float %arg)
509   ret float %arg
512 define half @fcmp_assume_issubnormal_callsite_arg_return(half %arg) {
513 ; CHECK-LABEL: define half @fcmp_assume_issubnormal_callsite_arg_return
514 ; CHECK-SAME: (half returned [[ARG:%.*]]) {
515 ; CHECK-NEXT:  entry:
516 ; CHECK-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) half @llvm.fabs.f16(half [[ARG]]) #[[ATTR20:[0-9]+]]
517 ; CHECK-NEXT:    [[IS_SUBNORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400
518 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_SUBNORMAL]]) #[[ATTR18]]
519 ; CHECK-NEXT:    call void @extern.use.f16(half [[ARG]])
520 ; CHECK-NEXT:    ret half [[ARG]]
522 entry:
523   %fabs = call half @llvm.fabs.f16(half %arg)
524   %is.subnormal = fcmp olt half %fabs, 0xH0400
525   call void @llvm.assume(i1 %is.subnormal)
526   call void @extern.use.f16(half %arg)
527   ret half %arg
530 ; Assume is after the call, shouldn't mark callsite.
531 define half @fcmp_assume_not_inf_after_call(half %arg) {
532 ; CHECK-LABEL: define half @fcmp_assume_not_inf_after_call
533 ; CHECK-SAME: (half returned [[ARG:%.*]]) {
534 ; CHECK-NEXT:  entry:
535 ; CHECK-NEXT:    call void @extern.use.f16(half [[ARG]])
536 ; CHECK-NEXT:    [[NOT_INF:%.*]] = fcmp oeq half [[ARG]], 0xH7C00
537 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[NOT_INF]])
538 ; CHECK-NEXT:    ret half [[ARG]]
540 entry:
541   call void @extern.use.f16(half %arg)
542   %not.inf = fcmp oeq half %arg, 0xH7C00
543   call void @llvm.assume(i1 %not.inf)
544   ret half %arg
547 ; Assume not subnormal or zero, and not infinity
548 define half @fcmp_assume2_callsite_arg_return(half %arg) {
549 ; CHECK-LABEL: define half @fcmp_assume2_callsite_arg_return
550 ; CHECK-SAME: (half returned [[ARG:%.*]]) {
551 ; CHECK-NEXT:  entry:
552 ; CHECK-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) half @llvm.fabs.f16(half [[ARG]]) #[[ATTR20]]
553 ; CHECK-NEXT:    [[NOT_SUBNORMAL_OR_ZERO:%.*]] = fcmp oge half [[FABS]], 0xH0400
554 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[NOT_SUBNORMAL_OR_ZERO]]) #[[ATTR18]]
555 ; CHECK-NEXT:    [[NOT_INF:%.*]] = fcmp one half [[ARG]], 0xH7C00
556 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[NOT_INF]]) #[[ATTR18]]
557 ; CHECK-NEXT:    call void @extern.use.f16(half [[ARG]])
558 ; CHECK-NEXT:    ret half [[ARG]]
560 entry:
561   %fabs = call half @llvm.fabs.f16(half %arg)
562   %not.subnormal.or.zero = fcmp oge half %fabs, 0xH0400
563   call void @llvm.assume(i1 %not.subnormal.or.zero)
565   %not.inf = fcmp one half %arg, 0xH7C00
566   call void @llvm.assume(i1 %not.inf)
568   call void @extern.use.f16(half %arg)
569   ret half %arg
572 define float @is_fpclass_assume_arg_return(float %arg) {
573 ; CHECK-LABEL: define float @is_fpclass_assume_arg_return
574 ; CHECK-SAME: (float returned [[ARG:%.*]]) {
575 ; CHECK-NEXT:  entry:
576 ; CHECK-NEXT:    [[CLASS_TEST:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG]], i32 noundef 292) #[[ATTR20]]
577 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[CLASS_TEST]]) #[[ATTR18]]
578 ; CHECK-NEXT:    call void @extern.use(float [[ARG]])
579 ; CHECK-NEXT:    ret float [[ARG]]
581 entry:
582   %class.test = call i1 @llvm.is.fpclass.f32(float %arg, i32 292)
583   call void @llvm.assume(i1 %class.test)
584   call void @extern.use(float %arg)
585   ret float %arg
588 ; Make sure we don't get confused by looking at an unrelated assume
589 ; based on the fabs of the value.
590 define half @assume_fcmp_fabs_with_other_fabs_assume(half %arg) {
591 ; CHECK-LABEL: define half @assume_fcmp_fabs_with_other_fabs_assume
592 ; CHECK-SAME: (half returned [[ARG:%.*]]) {
593 ; CHECK-NEXT:  entry:
594 ; CHECK-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) half @llvm.fabs.f16(half [[ARG]]) #[[ATTR20]]
595 ; CHECK-NEXT:    [[UNRELATED_FABS:%.*]] = fcmp one half [[FABS]], 0xH0000
596 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[UNRELATED_FABS]]) #[[ATTR18]]
597 ; CHECK-NEXT:    [[IS_SUBNORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400
598 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_SUBNORMAL]]) #[[ATTR18]]
599 ; CHECK-NEXT:    call void @extern.use.f16(half [[ARG]])
600 ; CHECK-NEXT:    call void @extern.use.f16(half nofpclass(ninf nzero nsub nnorm) [[FABS]])
601 ; CHECK-NEXT:    ret half [[ARG]]
603 entry:
605   %fabs = call half @llvm.fabs.f16(half %arg)
606   %unrelated.fabs = fcmp one half %fabs, 0.0
607   call void @llvm.assume(i1 %unrelated.fabs)
608   %is.subnormal = fcmp olt half %fabs, 0xH0400
609   call void @llvm.assume(i1 %is.subnormal)
610   call void @extern.use.f16(half %arg)
611   call void @extern.use.f16(half %fabs)
612   ret half %arg
615 ; Make sure if looking through the fabs finds a different source
616 ; value, we still identify a test mask by ignoring the fabs
617 define half @assume_fcmp_fabs_with_other_fabs_assume_fallback(half %arg) {
618 ; CHECK-LABEL: define half @assume_fcmp_fabs_with_other_fabs_assume_fallback
619 ; CHECK-SAME: (half returned [[ARG:%.*]]) {
620 ; CHECK-NEXT:  entry:
621 ; CHECK-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) half @llvm.fabs.f16(half [[ARG]]) #[[ATTR20]]
622 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR18]]
623 ; CHECK-NEXT:    [[UNRELATED_FABS:%.*]] = fcmp oeq half [[FABS]], 0xH0000
624 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[UNRELATED_FABS]]) #[[ATTR18]]
625 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR18]]
626 ; CHECK-NEXT:    call void @extern.use.f16(half [[ARG]])
627 ; CHECK-NEXT:    call void @extern.use.f16(half nofpclass(ninf nzero nsub nnorm) [[FABS]])
628 ; CHECK-NEXT:    ret half [[ARG]]
630 entry:
632   %fabs = call half @llvm.fabs.f16(half %arg)
634   %one.inf = fcmp one half %arg, 0xH7C00
635   call void @llvm.assume(i1 %one.inf)
637   %unrelated.fabs = fcmp oeq half %fabs, 0.0
638   call void @llvm.assume(i1 %unrelated.fabs)
640   %is.subnormal = fcmp olt half %fabs, 0xH0400
641   call void @llvm.assume(i1 %is.subnormal)
642   call void @extern.use.f16(half %arg)
643   call void @extern.use.f16(half %fabs)
644   ret half %arg
647 define float @assume_bundles(i1 %c, float %ret) {
648 ; CHECK-LABEL: define float @assume_bundles
649 ; CHECK-SAME: (i1 noundef [[C:%.*]], float returned [[RET:%.*]]) {
650 ; CHECK-NEXT:  entry:
651 ; CHECK-NEXT:    br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
652 ; CHECK:       A:
653 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR18]] [ "nofpclass"(float [[RET]], i32 3) ]
654 ; CHECK-NEXT:    call void @extern.use(float nofpclass(nan) [[RET]])
655 ; CHECK-NEXT:    ret float [[RET]]
656 ; CHECK:       B:
657 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) [ "nofpclass"(float [[RET]], i32 12) ]
658 ; CHECK-NEXT:    call void @extern.use(float nofpclass(ninf nnorm) [[RET]])
659 ; CHECK-NEXT:    ret float [[RET]]
661 entry:
662   br i1 %c, label %A, label %B
665   call void @llvm.assume(i1 true) [ "nofpclass"(float %ret, i32 3) ]
666   call void @extern.use(float %ret)
667   ret float %ret
670   call void @llvm.assume(i1 true) [ "nofpclass"(float %ret, i32 12) ]
671   call void @extern.use(float %ret)
672   ret float %ret
675 define float @returned_load(ptr %ptr) {
676 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
677 ; CHECK-LABEL: define float @returned_load
678 ; CHECK-SAME: (ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[PTR:%.*]]) #[[ATTR5:[0-9]+]] {
679 ; CHECK-NEXT:    [[LOAD:%.*]] = load float, ptr [[PTR]], align 4
680 ; CHECK-NEXT:    ret float [[LOAD]]
682   %load = load float, ptr %ptr
683   ret float %load
686 define float @pass_nofpclass_inf_through_memory(float nofpclass(inf) %arg) {
687 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
688 ; TUNIT-LABEL: define float @pass_nofpclass_inf_through_memory
689 ; TUNIT-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR3]] {
690 ; TUNIT-NEXT:    [[ALLOCA:%.*]] = alloca float, align 4
691 ; TUNIT-NEXT:    store float [[ARG]], ptr [[ALLOCA]], align 4
692 ; TUNIT-NEXT:    [[RET:%.*]] = call float @returned_load(ptr noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ALLOCA]]) #[[ATTR21:[0-9]+]]
693 ; TUNIT-NEXT:    ret float [[RET]]
695 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
696 ; CGSCC-LABEL: define float @pass_nofpclass_inf_through_memory
697 ; CGSCC-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR4]] {
698 ; CGSCC-NEXT:    [[ALLOCA:%.*]] = alloca float, align 4
699 ; CGSCC-NEXT:    store float [[ARG]], ptr [[ALLOCA]], align 4
700 ; CGSCC-NEXT:    [[RET:%.*]] = call float @returned_load(ptr noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ALLOCA]]) #[[ATTR21:[0-9]+]]
701 ; CGSCC-NEXT:    ret float [[RET]]
703   %alloca = alloca float
704   store float %arg, ptr %alloca
705   %ret = call float @returned_load(ptr %alloca)
706   ret float %ret
709 define float @returned_fabs(float %x) {
710 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
711 ; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs
712 ; TUNIT-SAME: (float [[X:%.*]]) #[[ATTR3]] {
713 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float [[X]]) #[[ATTR22:[0-9]+]]
714 ; TUNIT-NEXT:    ret float [[FABS]]
716 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
717 ; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs
718 ; CGSCC-SAME: (float [[X:%.*]]) #[[ATTR3]] {
719 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float [[X]]) #[[ATTR19]]
720 ; CGSCC-NEXT:    ret float [[FABS]]
722   %fabs = call float @llvm.fabs.f32(float %x)
723   ret float %fabs
726 define float @returned_fabs_nosnan(float nofpclass(snan) %x) {
727 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
728 ; TUNIT-LABEL: define nofpclass(snan ninf nzero nsub nnorm) float @returned_fabs_nosnan
729 ; TUNIT-SAME: (float nofpclass(snan) [[X:%.*]]) #[[ATTR3]] {
730 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(snan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(snan) [[X]]) #[[ATTR22]]
731 ; TUNIT-NEXT:    ret float [[FABS]]
733 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
734 ; CGSCC-LABEL: define nofpclass(snan ninf nzero nsub nnorm) float @returned_fabs_nosnan
735 ; CGSCC-SAME: (float nofpclass(snan) [[X:%.*]]) #[[ATTR3]] {
736 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(snan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(snan) [[X]]) #[[ATTR19]]
737 ; CGSCC-NEXT:    ret float [[FABS]]
739   %fabs = call float @llvm.fabs.f32(float %x)
740   ret float %fabs
743 define float @returned_fabs_noqnan(float nofpclass(qnan) %x) {
744 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
745 ; TUNIT-LABEL: define nofpclass(qnan ninf nzero nsub nnorm) float @returned_fabs_noqnan
746 ; TUNIT-SAME: (float nofpclass(qnan) [[X:%.*]]) #[[ATTR3]] {
747 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(qnan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(qnan) [[X]]) #[[ATTR22]]
748 ; TUNIT-NEXT:    ret float [[FABS]]
750 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
751 ; CGSCC-LABEL: define nofpclass(qnan ninf nzero nsub nnorm) float @returned_fabs_noqnan
752 ; CGSCC-SAME: (float nofpclass(qnan) [[X:%.*]]) #[[ATTR3]] {
753 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(qnan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(qnan) [[X]]) #[[ATTR19]]
754 ; CGSCC-NEXT:    ret float [[FABS]]
756   %fabs = call float @llvm.fabs.f32(float %x)
757   ret float %fabs
760 define float @returned_fabs_nonan(float nofpclass(nan) %x) {
761 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
762 ; TUNIT-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @returned_fabs_nonan
763 ; TUNIT-SAME: (float nofpclass(nan) [[X:%.*]]) #[[ATTR3]] {
764 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(nan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nan) [[X]]) #[[ATTR22]]
765 ; TUNIT-NEXT:    ret float [[FABS]]
767 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
768 ; CGSCC-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @returned_fabs_nonan
769 ; CGSCC-SAME: (float nofpclass(nan) [[X:%.*]]) #[[ATTR3]] {
770 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(nan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nan) [[X]]) #[[ATTR19]]
771 ; CGSCC-NEXT:    ret float [[FABS]]
773   %fabs = call float @llvm.fabs.f32(float %x)
774   ret float %fabs
777 define float @returned_fabs_noinf(float nofpclass(inf) %x) {
778 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
779 ; TUNIT-LABEL: define nofpclass(inf nzero nsub nnorm) float @returned_fabs_noinf
780 ; TUNIT-SAME: (float nofpclass(inf) [[X:%.*]]) #[[ATTR3]] {
781 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(inf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(inf) [[X]]) #[[ATTR22]]
782 ; TUNIT-NEXT:    ret float [[FABS]]
784 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
785 ; CGSCC-LABEL: define nofpclass(inf nzero nsub nnorm) float @returned_fabs_noinf
786 ; CGSCC-SAME: (float nofpclass(inf) [[X:%.*]]) #[[ATTR3]] {
787 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(inf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(inf) [[X]]) #[[ATTR19]]
788 ; CGSCC-NEXT:    ret float [[FABS]]
790   %fabs = call float @llvm.fabs.f32(float %x)
791   ret float %fabs
794 define float @returned_fabs_nopos(float nofpclass(psub pnorm pinf) %x) {
795 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
796 ; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nopos
797 ; TUNIT-SAME: (float nofpclass(pinf psub pnorm) [[X:%.*]]) #[[ATTR3]] {
798 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(pinf psub pnorm) [[X]]) #[[ATTR22]]
799 ; TUNIT-NEXT:    ret float [[FABS]]
801 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
802 ; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nopos
803 ; CGSCC-SAME: (float nofpclass(pinf psub pnorm) [[X:%.*]]) #[[ATTR3]] {
804 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(pinf psub pnorm) [[X]]) #[[ATTR19]]
805 ; CGSCC-NEXT:    ret float [[FABS]]
807   %fabs = call float @llvm.fabs.f32(float %x)
808   ret float %fabs
811 define float @returned_fabs_nopos_nopzero(float nofpclass(psub pnorm pinf pzero) %x) {
812 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
813 ; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nopos_nopzero
814 ; TUNIT-SAME: (float nofpclass(pinf pzero psub pnorm) [[X:%.*]]) #[[ATTR3]] {
815 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(pinf pzero psub pnorm) [[X]]) #[[ATTR22]]
816 ; TUNIT-NEXT:    ret float [[FABS]]
818 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
819 ; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nopos_nopzero
820 ; CGSCC-SAME: (float nofpclass(pinf pzero psub pnorm) [[X:%.*]]) #[[ATTR3]] {
821 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(pinf pzero psub pnorm) [[X]]) #[[ATTR19]]
822 ; CGSCC-NEXT:    ret float [[FABS]]
824   %fabs = call float @llvm.fabs.f32(float %x)
825   ret float %fabs
828 define float @returned_fabs_nopos_nozero(float nofpclass(psub pnorm pinf zero) %x) {
829 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
830 ; TUNIT-LABEL: define nofpclass(ninf zero nsub nnorm) float @returned_fabs_nopos_nozero
831 ; TUNIT-SAME: (float nofpclass(pinf zero psub pnorm) [[X:%.*]]) #[[ATTR3]] {
832 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf zero nsub nnorm) float @llvm.fabs.f32(float nofpclass(pinf zero psub pnorm) [[X]]) #[[ATTR22]]
833 ; TUNIT-NEXT:    ret float [[FABS]]
835 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
836 ; CGSCC-LABEL: define nofpclass(ninf zero nsub nnorm) float @returned_fabs_nopos_nozero
837 ; CGSCC-SAME: (float nofpclass(pinf zero psub pnorm) [[X:%.*]]) #[[ATTR3]] {
838 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf zero nsub nnorm) float @llvm.fabs.f32(float nofpclass(pinf zero psub pnorm) [[X]]) #[[ATTR19]]
839 ; CGSCC-NEXT:    ret float [[FABS]]
841   %fabs = call float @llvm.fabs.f32(float %x)
842   ret float %fabs
845 define float @returned_fabs_nopos_nonan(float nofpclass(psub pnorm pinf nan) %x) {
846 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
847 ; TUNIT-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @returned_fabs_nopos_nonan
848 ; TUNIT-SAME: (float nofpclass(nan pinf psub pnorm) [[X:%.*]]) #[[ATTR3]] {
849 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(nan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nan pinf psub pnorm) [[X]]) #[[ATTR22]]
850 ; TUNIT-NEXT:    ret float [[FABS]]
852 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
853 ; CGSCC-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @returned_fabs_nopos_nonan
854 ; CGSCC-SAME: (float nofpclass(nan pinf psub pnorm) [[X:%.*]]) #[[ATTR3]] {
855 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(nan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nan pinf psub pnorm) [[X]]) #[[ATTR19]]
856 ; CGSCC-NEXT:    ret float [[FABS]]
858   %fabs = call float @llvm.fabs.f32(float %x)
859   ret float %fabs
862 define float @returned_fabs_noneg(float nofpclass(nsub nnorm ninf) %x) {
863 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
864 ; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_noneg
865 ; TUNIT-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
866 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf nsub nnorm) [[X]]) #[[ATTR22]]
867 ; TUNIT-NEXT:    ret float [[FABS]]
869 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
870 ; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_noneg
871 ; CGSCC-SAME: (float nofpclass(ninf nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
872 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf nsub nnorm) [[X]]) #[[ATTR19]]
873 ; CGSCC-NEXT:    ret float [[FABS]]
875   %fabs = call float @llvm.fabs.f32(float %x)
876   ret float %fabs
879 define float @returned_fabs_noneg_nonzero(float nofpclass(nsub nnorm ninf nzero) %x) {
880 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
881 ; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_noneg_nonzero
882 ; TUNIT-SAME: (float nofpclass(ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
883 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf nzero nsub nnorm) [[X]]) #[[ATTR22]]
884 ; TUNIT-NEXT:    ret float [[FABS]]
886 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
887 ; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_noneg_nonzero
888 ; CGSCC-SAME: (float nofpclass(ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
889 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf nzero nsub nnorm) [[X]]) #[[ATTR19]]
890 ; CGSCC-NEXT:    ret float [[FABS]]
892   %fabs = call float @llvm.fabs.f32(float %x)
893   ret float %fabs
896 define float @returned_fabs_noneg_nozero(float nofpclass(nsub nnorm ninf zero) %x) {
897 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
898 ; TUNIT-LABEL: define nofpclass(ninf zero nsub nnorm) float @returned_fabs_noneg_nozero
899 ; TUNIT-SAME: (float nofpclass(ninf zero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
900 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf zero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf zero nsub nnorm) [[X]]) #[[ATTR22]]
901 ; TUNIT-NEXT:    ret float [[FABS]]
903 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
904 ; CGSCC-LABEL: define nofpclass(ninf zero nsub nnorm) float @returned_fabs_noneg_nozero
905 ; CGSCC-SAME: (float nofpclass(ninf zero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
906 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf zero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf zero nsub nnorm) [[X]]) #[[ATTR19]]
907 ; CGSCC-NEXT:    ret float [[FABS]]
909   %fabs = call float @llvm.fabs.f32(float %x)
910   ret float %fabs
913 define float @returned_fabs_noneg_nonan(float nofpclass(nsub nnorm ninf nan) %x) {
914 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
915 ; TUNIT-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @returned_fabs_noneg_nonan
916 ; TUNIT-SAME: (float nofpclass(nan ninf nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
917 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(nan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nan ninf nsub nnorm) [[X]]) #[[ATTR22]]
918 ; TUNIT-NEXT:    ret float [[FABS]]
920 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
921 ; CGSCC-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @returned_fabs_noneg_nonan
922 ; CGSCC-SAME: (float nofpclass(nan ninf nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
923 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(nan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nan ninf nsub nnorm) [[X]]) #[[ATTR19]]
924 ; CGSCC-NEXT:    ret float [[FABS]]
926   %fabs = call float @llvm.fabs.f32(float %x)
927   ret float %fabs
930 define float @returned_fabs_nonsub_nopnorm_nonzero(float nofpclass(nsub pnorm nzero) %x) {
931 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
932 ; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nonsub_nopnorm_nonzero
933 ; TUNIT-SAME: (float nofpclass(nzero nsub pnorm) [[X:%.*]]) #[[ATTR3]] {
934 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nzero nsub pnorm) [[X]]) #[[ATTR22]]
935 ; TUNIT-NEXT:    ret float [[FABS]]
937 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
938 ; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nonsub_nopnorm_nonzero
939 ; CGSCC-SAME: (float nofpclass(nzero nsub pnorm) [[X:%.*]]) #[[ATTR3]] {
940 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nzero nsub pnorm) [[X]]) #[[ATTR19]]
941 ; CGSCC-NEXT:    ret float [[FABS]]
943   %fabs = call float @llvm.fabs.f32(float %x)
944   ret float %fabs
947 define float @returned_fabs_nopsub_nonnorm_nopzero(float nofpclass(psub nnorm pzero) %x) {
948 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
949 ; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nopsub_nonnorm_nopzero
950 ; TUNIT-SAME: (float nofpclass(pzero psub nnorm) [[X:%.*]]) #[[ATTR3]] {
951 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(pzero psub nnorm) [[X]]) #[[ATTR22]]
952 ; TUNIT-NEXT:    ret float [[FABS]]
954 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
955 ; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nopsub_nonnorm_nopzero
956 ; CGSCC-SAME: (float nofpclass(pzero psub nnorm) [[X:%.*]]) #[[ATTR3]] {
957 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(pzero psub nnorm) [[X]]) #[[ATTR19]]
958 ; CGSCC-NEXT:    ret float [[FABS]]
960   %fabs = call float @llvm.fabs.f32(float %x)
961   ret float %fabs
964 define float @returned_fabs_nonnorm_nozero(float nofpclass(nnorm nzero) %x) {
965 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
966 ; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nonnorm_nozero
967 ; TUNIT-SAME: (float nofpclass(nzero nnorm) [[X:%.*]]) #[[ATTR3]] {
968 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nzero nnorm) [[X]]) #[[ATTR22]]
969 ; TUNIT-NEXT:    ret float [[FABS]]
971 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
972 ; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nonnorm_nozero
973 ; CGSCC-SAME: (float nofpclass(nzero nnorm) [[X:%.*]]) #[[ATTR3]] {
974 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nzero nnorm) [[X]]) #[[ATTR19]]
975 ; CGSCC-NEXT:    ret float [[FABS]]
977   %fabs = call float @llvm.fabs.f32(float %x)
978   ret float %fabs
981 define float @returned_fneg(float %x) {
982 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
983 ; CHECK-LABEL: define float @returned_fneg
984 ; CHECK-SAME: (float [[X:%.*]]) #[[ATTR3]] {
985 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
986 ; CHECK-NEXT:    ret float [[FNEG]]
988   %fneg = fneg float %x
989   ret float %fneg
992 define float @returned_fneg_nosnan(float nofpclass(snan) %x) {
993 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
994 ; CHECK-LABEL: define nofpclass(snan) float @returned_fneg_nosnan
995 ; CHECK-SAME: (float nofpclass(snan) [[X:%.*]]) #[[ATTR3]] {
996 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
997 ; CHECK-NEXT:    ret float [[FNEG]]
999   %fneg = fneg float %x
1000   ret float %fneg
1003 define float @returned_fneg_noqnan(float nofpclass(qnan) %x) {
1004 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1005 ; CHECK-LABEL: define nofpclass(qnan) float @returned_fneg_noqnan
1006 ; CHECK-SAME: (float nofpclass(qnan) [[X:%.*]]) #[[ATTR3]] {
1007 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
1008 ; CHECK-NEXT:    ret float [[FNEG]]
1010   %fneg = fneg float %x
1011   ret float %fneg
1014 define float @returned_fneg_nosnan_ninf_flag(float nofpclass(snan) %x) {
1015 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1016 ; CHECK-LABEL: define nofpclass(snan inf) float @returned_fneg_nosnan_ninf_flag
1017 ; CHECK-SAME: (float nofpclass(snan) [[X:%.*]]) #[[ATTR3]] {
1018 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg ninf float [[X]]
1019 ; CHECK-NEXT:    ret float [[FNEG]]
1021   %fneg = fneg ninf float %x
1022   ret float %fneg
1025 define float @returned_fneg_nonan(float nofpclass(nan) %x) {
1026 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1027 ; CHECK-LABEL: define nofpclass(nan) float @returned_fneg_nonan
1028 ; CHECK-SAME: (float nofpclass(nan) [[X:%.*]]) #[[ATTR3]] {
1029 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
1030 ; CHECK-NEXT:    ret float [[FNEG]]
1032   %fneg = fneg float %x
1033   ret float %fneg
1036 define float @returned_fneg_noinf(float nofpclass(inf) %x) {
1037 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1038 ; CHECK-LABEL: define nofpclass(inf) float @returned_fneg_noinf
1039 ; CHECK-SAME: (float nofpclass(inf) [[X:%.*]]) #[[ATTR3]] {
1040 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
1041 ; CHECK-NEXT:    ret float [[FNEG]]
1043   %fneg = fneg float %x
1044   ret float %fneg
1047 define float @returned_fneg_noneg(float nofpclass(ninf nsub nnorm nzero) %x) {
1048 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1049 ; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @returned_fneg_noneg
1050 ; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
1051 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
1052 ; CHECK-NEXT:    ret float [[FNEG]]
1054   %fneg = fneg float %x
1055   ret float %fneg
1058 define float @returned_fneg_noneg_nnan_flag(float nofpclass(ninf nsub nnorm nzero) %x) {
1059 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1060 ; CHECK-LABEL: define nofpclass(nan pinf pzero psub pnorm) float @returned_fneg_noneg_nnan_flag
1061 ; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
1062 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg nnan float [[X]]
1063 ; CHECK-NEXT:    ret float [[FNEG]]
1065   %fneg = fneg nnan float %x
1066   ret float %fneg
1069 define float @returned_fneg_nonsubnnorm(float nofpclass(nsub nnorm) %x) {
1070 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1071 ; CHECK-LABEL: define nofpclass(psub pnorm) float @returned_fneg_nonsubnnorm
1072 ; CHECK-SAME: (float nofpclass(nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
1073 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
1074 ; CHECK-NEXT:    ret float [[FNEG]]
1076   %fneg = fneg float %x
1077   ret float %fneg
1080 define float @returned_fneg_nopos(float nofpclass(pinf psub pnorm pzero) %x) {
1081 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1082 ; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fneg_nopos
1083 ; CHECK-SAME: (float nofpclass(pinf pzero psub pnorm) [[X:%.*]]) #[[ATTR3]] {
1084 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
1085 ; CHECK-NEXT:    ret float [[FNEG]]
1087   %fneg = fneg float %x
1088   ret float %fneg
1091 define float @returned_fneg_nopnormpsub(float nofpclass(psub pnorm) %x) {
1092 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1093 ; CHECK-LABEL: define nofpclass(nsub nnorm) float @returned_fneg_nopnormpsub
1094 ; CHECK-SAME: (float nofpclass(psub pnorm) [[X:%.*]]) #[[ATTR3]] {
1095 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
1096 ; CHECK-NEXT:    ret float [[FNEG]]
1098   %fneg = fneg float %x
1099   ret float %fneg
1102 define float @returned_fneg_mixed(float nofpclass(psub nnorm nzero qnan ninf) %x) {
1103 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1104 ; CHECK-LABEL: define nofpclass(qnan pinf pzero nsub pnorm) float @returned_fneg_mixed
1105 ; CHECK-SAME: (float nofpclass(qnan ninf nzero psub nnorm) [[X:%.*]]) #[[ATTR3]] {
1106 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
1107 ; CHECK-NEXT:    ret float [[FNEG]]
1109   %fneg = fneg float %x
1110   ret float %fneg
1113 define float @returned_fneg_fabs(float %x) {
1114 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1115 ; TUNIT-LABEL: define nofpclass(pinf pzero psub pnorm) float @returned_fneg_fabs
1116 ; TUNIT-SAME: (float [[X:%.*]]) #[[ATTR3]] {
1117 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float [[X]]) #[[ATTR22]]
1118 ; TUNIT-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1119 ; TUNIT-NEXT:    ret float [[FNEG_FABS]]
1121 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1122 ; CGSCC-LABEL: define nofpclass(pinf pzero psub pnorm) float @returned_fneg_fabs
1123 ; CGSCC-SAME: (float [[X:%.*]]) #[[ATTR3]] {
1124 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float [[X]]) #[[ATTR19]]
1125 ; CGSCC-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1126 ; CGSCC-NEXT:    ret float [[FNEG_FABS]]
1128   %fabs = call float @llvm.fabs.f32(float %x)
1129   %fneg.fabs = fneg float %fabs
1130   ret float %fneg.fabs
1133 define float @returned_fneg_fabs_nosnan(float nofpclass(snan) %x) {
1134 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1135 ; TUNIT-LABEL: define nofpclass(snan pinf pzero psub pnorm) float @returned_fneg_fabs_nosnan
1136 ; TUNIT-SAME: (float nofpclass(snan) [[X:%.*]]) #[[ATTR3]] {
1137 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(snan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(snan) [[X]]) #[[ATTR22]]
1138 ; TUNIT-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1139 ; TUNIT-NEXT:    ret float [[FNEG_FABS]]
1141 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1142 ; CGSCC-LABEL: define nofpclass(snan pinf pzero psub pnorm) float @returned_fneg_fabs_nosnan
1143 ; CGSCC-SAME: (float nofpclass(snan) [[X:%.*]]) #[[ATTR3]] {
1144 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(snan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(snan) [[X]]) #[[ATTR19]]
1145 ; CGSCC-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1146 ; CGSCC-NEXT:    ret float [[FNEG_FABS]]
1148   %fabs = call float @llvm.fabs.f32(float %x)
1149   %fneg.fabs = fneg float %fabs
1150   ret float %fneg.fabs
1153 define float @returned_fneg_fabs_noqnan(float nofpclass(qnan) %x) {
1154 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1155 ; TUNIT-LABEL: define nofpclass(qnan pinf pzero psub pnorm) float @returned_fneg_fabs_noqnan
1156 ; TUNIT-SAME: (float nofpclass(qnan) [[X:%.*]]) #[[ATTR3]] {
1157 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(qnan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(qnan) [[X]]) #[[ATTR22]]
1158 ; TUNIT-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1159 ; TUNIT-NEXT:    ret float [[FNEG_FABS]]
1161 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1162 ; CGSCC-LABEL: define nofpclass(qnan pinf pzero psub pnorm) float @returned_fneg_fabs_noqnan
1163 ; CGSCC-SAME: (float nofpclass(qnan) [[X:%.*]]) #[[ATTR3]] {
1164 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(qnan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(qnan) [[X]]) #[[ATTR19]]
1165 ; CGSCC-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1166 ; CGSCC-NEXT:    ret float [[FNEG_FABS]]
1168   %fabs = call float @llvm.fabs.f32(float %x)
1169   %fneg.fabs = fneg float %fabs
1170   ret float %fneg.fabs
1173 define float @returned_fneg_fabs_nonan(float nofpclass(nan) %x) {
1174 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1175 ; TUNIT-LABEL: define nofpclass(nan pinf pzero psub pnorm) float @returned_fneg_fabs_nonan
1176 ; TUNIT-SAME: (float nofpclass(nan) [[X:%.*]]) #[[ATTR3]] {
1177 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(nan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nan) [[X]]) #[[ATTR22]]
1178 ; TUNIT-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1179 ; TUNIT-NEXT:    ret float [[FNEG_FABS]]
1181 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1182 ; CGSCC-LABEL: define nofpclass(nan pinf pzero psub pnorm) float @returned_fneg_fabs_nonan
1183 ; CGSCC-SAME: (float nofpclass(nan) [[X:%.*]]) #[[ATTR3]] {
1184 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(nan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nan) [[X]]) #[[ATTR19]]
1185 ; CGSCC-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1186 ; CGSCC-NEXT:    ret float [[FNEG_FABS]]
1188   %fabs = call float @llvm.fabs.f32(float %x)
1189   %fneg.fabs = fneg float %fabs
1190   ret float %fneg.fabs
1193 define float @returned_fneg_fabs_noneg(float nofpclass(ninf nsub nnorm nzero) %x) {
1194 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1195 ; TUNIT-LABEL: define nofpclass(pinf pzero psub pnorm) float @returned_fneg_fabs_noneg
1196 ; TUNIT-SAME: (float nofpclass(ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
1197 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf nzero nsub nnorm) [[X]]) #[[ATTR22]]
1198 ; TUNIT-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1199 ; TUNIT-NEXT:    ret float [[FNEG_FABS]]
1201 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1202 ; CGSCC-LABEL: define nofpclass(pinf pzero psub pnorm) float @returned_fneg_fabs_noneg
1203 ; CGSCC-SAME: (float nofpclass(ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
1204 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf nzero nsub nnorm) [[X]]) #[[ATTR19]]
1205 ; CGSCC-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1206 ; CGSCC-NEXT:    ret float [[FNEG_FABS]]
1208   %fabs = call float @llvm.fabs.f32(float %x)
1209   %fneg.fabs = fneg float %fabs
1210   ret float %fneg.fabs
1213 define float @returned_fneg_fabs_nopos(float nofpclass(pinf psub pnorm pzero) %x) {
1214 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1215 ; TUNIT-LABEL: define nofpclass(pinf pzero psub pnorm) float @returned_fneg_fabs_nopos
1216 ; TUNIT-SAME: (float nofpclass(pinf pzero psub pnorm) [[X:%.*]]) #[[ATTR3]] {
1217 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(pinf pzero psub pnorm) [[X]]) #[[ATTR22]]
1218 ; TUNIT-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1219 ; TUNIT-NEXT:    ret float [[FNEG_FABS]]
1221 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1222 ; CGSCC-LABEL: define nofpclass(pinf pzero psub pnorm) float @returned_fneg_fabs_nopos
1223 ; CGSCC-SAME: (float nofpclass(pinf pzero psub pnorm) [[X:%.*]]) #[[ATTR3]] {
1224 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(pinf pzero psub pnorm) [[X]]) #[[ATTR19]]
1225 ; CGSCC-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1226 ; CGSCC-NEXT:    ret float [[FNEG_FABS]]
1228   %fabs = call float @llvm.fabs.f32(float %x)
1229   %fneg.fabs = fneg float %fabs
1230   ret float %fneg.fabs
1233 define float @returned_fneg_fabs_mixed(float nofpclass(psub nnorm nzero qnan ninf) %x) {
1234 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1235 ; TUNIT-LABEL: define nofpclass(qnan pinf pzero psub pnorm) float @returned_fneg_fabs_mixed
1236 ; TUNIT-SAME: (float nofpclass(qnan ninf nzero psub nnorm) [[X:%.*]]) #[[ATTR3]] {
1237 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(qnan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(qnan ninf nzero psub nnorm) [[X]]) #[[ATTR22]]
1238 ; TUNIT-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1239 ; TUNIT-NEXT:    ret float [[FNEG_FABS]]
1241 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1242 ; CGSCC-LABEL: define nofpclass(qnan pinf pzero psub pnorm) float @returned_fneg_fabs_mixed
1243 ; CGSCC-SAME: (float nofpclass(qnan ninf nzero psub nnorm) [[X:%.*]]) #[[ATTR3]] {
1244 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(qnan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(qnan ninf nzero psub nnorm) [[X]]) #[[ATTR19]]
1245 ; CGSCC-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1246 ; CGSCC-NEXT:    ret float [[FNEG_FABS]]
1248   %fabs = call float @llvm.fabs.f32(float %x)
1249   %fneg.fabs = fneg float %fabs
1250   ret float %fneg.fabs
1253 define float @returned_fneg_fabs_ninf_flag_fabs(float %x) {
1254 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1255 ; TUNIT-LABEL: define nofpclass(inf pzero psub pnorm) float @returned_fneg_fabs_ninf_flag_fabs
1256 ; TUNIT-SAME: (float [[X:%.*]]) #[[ATTR3]] {
1257 ; TUNIT-NEXT:    [[FABS:%.*]] = call ninf nofpclass(inf nzero nsub nnorm) float @llvm.fabs.f32(float [[X]]) #[[ATTR22]]
1258 ; TUNIT-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1259 ; TUNIT-NEXT:    ret float [[FNEG_FABS]]
1261 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1262 ; CGSCC-LABEL: define nofpclass(inf pzero psub pnorm) float @returned_fneg_fabs_ninf_flag_fabs
1263 ; CGSCC-SAME: (float [[X:%.*]]) #[[ATTR3]] {
1264 ; CGSCC-NEXT:    [[FABS:%.*]] = call ninf nofpclass(inf nzero nsub nnorm) float @llvm.fabs.f32(float [[X]]) #[[ATTR19]]
1265 ; CGSCC-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1266 ; CGSCC-NEXT:    ret float [[FNEG_FABS]]
1268   %fabs = call ninf float @llvm.fabs.f32(float %x)
1269   %fneg.fabs = fneg float %fabs
1270   ret float %fneg.fabs
1273 define float @returned_fneg_fabs_ninf_flag_fneg(float %x) {
1274 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1275 ; TUNIT-LABEL: define nofpclass(inf pzero psub pnorm) float @returned_fneg_fabs_ninf_flag_fneg
1276 ; TUNIT-SAME: (float [[X:%.*]]) #[[ATTR3]] {
1277 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float [[X]]) #[[ATTR22]]
1278 ; TUNIT-NEXT:    [[FNEG_FABS:%.*]] = fneg ninf float [[FABS]]
1279 ; TUNIT-NEXT:    ret float [[FNEG_FABS]]
1281 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1282 ; CGSCC-LABEL: define nofpclass(inf pzero psub pnorm) float @returned_fneg_fabs_ninf_flag_fneg
1283 ; CGSCC-SAME: (float [[X:%.*]]) #[[ATTR3]] {
1284 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float [[X]]) #[[ATTR19]]
1285 ; CGSCC-NEXT:    [[FNEG_FABS:%.*]] = fneg ninf float [[FABS]]
1286 ; CGSCC-NEXT:    ret float [[FNEG_FABS]]
1288   %fabs = call float @llvm.fabs.f32(float %x)
1289   %fneg.fabs = fneg ninf float %fabs
1290   ret float %fneg.fabs
1293 define float @uitofp_i32_to_f32(i32 %arg) {
1294 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1295 ; CHECK-LABEL: define nofpclass(nan inf nzero sub nnorm) float @uitofp_i32_to_f32
1296 ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] {
1297 ; CHECK-NEXT:    [[CVT:%.*]] = uitofp i32 [[ARG]] to float
1298 ; CHECK-NEXT:    ret float [[CVT]]
1300   %cvt = uitofp i32 %arg to float
1301   ret float %cvt
1304 define float @sitofp_i32_to_f32(i32 %arg) {
1305 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1306 ; CHECK-LABEL: define nofpclass(nan inf nzero sub) float @sitofp_i32_to_f32
1307 ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] {
1308 ; CHECK-NEXT:    [[CVT:%.*]] = sitofp i32 [[ARG]] to float
1309 ; CHECK-NEXT:    ret float [[CVT]]
1311   %cvt = sitofp i32 %arg to float
1312   ret float %cvt
1315 define <2 x float> @uitofp_v2i32_to_v2f32(<2 x i32> %arg) {
1316 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1317 ; CHECK-LABEL: define nofpclass(nan inf nzero sub nnorm) <2 x float> @uitofp_v2i32_to_v2f32
1318 ; CHECK-SAME: (<2 x i32> [[ARG:%.*]]) #[[ATTR3]] {
1319 ; CHECK-NEXT:    [[CVT:%.*]] = uitofp <2 x i32> [[ARG]] to <2 x float>
1320 ; CHECK-NEXT:    ret <2 x float> [[CVT]]
1322   %cvt = uitofp <2 x i32> %arg to <2 x float>
1323   ret <2 x float> %cvt
1326 define <2 x float> @sitofp_v2i32_to_v2i32(<2 x i32> %arg) {
1327 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1328 ; CHECK-LABEL: define nofpclass(nan inf nzero sub) <2 x float> @sitofp_v2i32_to_v2i32
1329 ; CHECK-SAME: (<2 x i32> [[ARG:%.*]]) #[[ATTR3]] {
1330 ; CHECK-NEXT:    [[CVT:%.*]] = sitofp <2 x i32> [[ARG]] to <2 x float>
1331 ; CHECK-NEXT:    ret <2 x float> [[CVT]]
1333   %cvt = sitofp <2 x i32> %arg to <2 x float>
1334   ret <2 x float> %cvt
1337 define half @uitofp_i17_to_f16(i17 %arg) {
1338 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1339 ; CHECK-LABEL: define nofpclass(nan ninf nzero sub nnorm) half @uitofp_i17_to_f16
1340 ; CHECK-SAME: (i17 [[ARG:%.*]]) #[[ATTR3]] {
1341 ; CHECK-NEXT:    [[CVT:%.*]] = uitofp i17 [[ARG]] to half
1342 ; CHECK-NEXT:    ret half [[CVT]]
1344   %cvt = uitofp i17 %arg to half
1345   ret half %cvt
1348 define half @sitofp_i17_to_f16(i17 %arg) {
1349 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1350 ; CHECK-LABEL: define nofpclass(nan nzero sub) half @sitofp_i17_to_f16
1351 ; CHECK-SAME: (i17 [[ARG:%.*]]) #[[ATTR3]] {
1352 ; CHECK-NEXT:    [[CVT:%.*]] = sitofp i17 [[ARG]] to half
1353 ; CHECK-NEXT:    ret half [[CVT]]
1355   %cvt = sitofp i17 %arg to half
1356   ret half %cvt
1359 define <2 x half> @uitofp_v2i17_to_v2f16(<2 x i17> %arg) {
1360 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1361 ; CHECK-LABEL: define nofpclass(nan ninf nzero sub nnorm) <2 x half> @uitofp_v2i17_to_v2f16
1362 ; CHECK-SAME: (<2 x i17> [[ARG:%.*]]) #[[ATTR3]] {
1363 ; CHECK-NEXT:    [[CVT:%.*]] = uitofp <2 x i17> [[ARG]] to <2 x half>
1364 ; CHECK-NEXT:    ret <2 x half> [[CVT]]
1366   %cvt = uitofp <2 x i17> %arg to <2 x half>
1367   ret <2 x half> %cvt
1370 define <2 x half> @sitofp_v2i17_to_v2i17(<2 x i17> %arg) {
1371 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1372 ; CHECK-LABEL: define nofpclass(nan nzero sub) <2 x half> @sitofp_v2i17_to_v2i17
1373 ; CHECK-SAME: (<2 x i17> [[ARG:%.*]]) #[[ATTR3]] {
1374 ; CHECK-NEXT:    [[CVT:%.*]] = sitofp <2 x i17> [[ARG]] to <2 x half>
1375 ; CHECK-NEXT:    ret <2 x half> [[CVT]]
1377   %cvt = sitofp <2 x i17> %arg to <2 x half>
1378   ret <2 x half> %cvt
1381 define float @assume_intersection_not_zero_and_not_nan(float %arg) {
1382 ; CHECK-LABEL: define float @assume_intersection_not_zero_and_not_nan
1383 ; CHECK-SAME: (float returned [[ARG:%.*]]) {
1384 ; CHECK-NEXT:  entry:
1385 ; CHECK-NEXT:    [[IS_NOT_ZERO_OR_NAN:%.*]] = fcmp une float [[ARG]], 0.000000e+00
1386 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_NOT_ZERO_OR_NAN]]) #[[ATTR18]]
1387 ; CHECK-NEXT:    [[IS_ORD:%.*]] = fcmp ord float [[ARG]], 0.000000e+00
1388 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_ORD]]) #[[ATTR18]]
1389 ; CHECK-NEXT:    call void @extern.use(float [[ARG]])
1390 ; CHECK-NEXT:    ret float [[ARG]]
1392 entry:
1393   %is.not.zero.or.nan = fcmp une float %arg, 0.0
1394   call void @llvm.assume(i1 %is.not.zero.or.nan)
1395   %is.ord = fcmp ord float %arg, 0.0
1396   call void @llvm.assume(i1 %is.ord)
1397   call void @extern.use(float %arg)
1398   ret float %arg
1401 define float @assume_intersection_class(float %arg) {
1402 ; CHECK-LABEL: define float @assume_intersection_class
1403 ; CHECK-SAME: (float returned [[ARG:%.*]]) {
1404 ; CHECK-NEXT:  entry:
1405 ; CHECK-NEXT:    [[POS_NORMAL_OR_POS_SUBNORMAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG]], i32 noundef 384) #[[ATTR20]]
1406 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[POS_NORMAL_OR_POS_SUBNORMAL]]) #[[ATTR18]]
1407 ; CHECK-NEXT:    [[IS_NORMAL:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG]], i32 noundef 264) #[[ATTR20]]
1408 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_NORMAL]]) #[[ATTR18]]
1409 ; CHECK-NEXT:    call void @extern.use(float [[ARG]])
1410 ; CHECK-NEXT:    ret float [[ARG]]
1412 entry:
1413   %pos.normal.or.pos.subnormal = call i1 @llvm.is.fpclass.f32(float %arg, i32 384)
1414   call void @llvm.assume(i1 %pos.normal.or.pos.subnormal)
1415   %is.normal = call i1 @llvm.is.fpclass.f32(float %arg, i32 264)
1416   call void @llvm.assume(i1 %is.normal)
1418   call void @extern.use(float %arg)
1419   ret float %arg
1422 define float @assume_intersection_none(float %arg) {
1423 ; CHECK-LABEL: define float @assume_intersection_none
1424 ; CHECK-SAME: (float returned [[ARG:%.*]]) {
1425 ; CHECK-NEXT:  entry:
1426 ; CHECK-NEXT:    [[CLASS1:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG]], i32 noundef 682) #[[ATTR20]]
1427 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[CLASS1]]) #[[ATTR18]]
1428 ; CHECK-NEXT:    [[CLASS2:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG]], i32 noundef 341) #[[ATTR20]]
1429 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[CLASS2]]) #[[ATTR18]]
1430 ; CHECK-NEXT:    call void @extern.use(float [[ARG]])
1431 ; CHECK-NEXT:    ret float [[ARG]]
1433 entry:
1434   %class1 = call i1 @llvm.is.fpclass.f32(float %arg, i32 682)
1435   call void @llvm.assume(i1 %class1)
1436   %class2 = call i1 @llvm.is.fpclass.f32(float %arg, i32 341)
1437   call void @llvm.assume(i1 %class2)
1438   call void @extern.use(float %arg)
1439   ret float %arg
1442 define float @returned_extractelement_dynamic_index(<4 x float> nofpclass(nan) %vec, i32 %idx) {
1443 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1444 ; CHECK-LABEL: define nofpclass(nan) float @returned_extractelement_dynamic_index
1445 ; CHECK-SAME: (<4 x float> nofpclass(nan) [[VEC:%.*]], i32 [[IDX:%.*]]) #[[ATTR3]] {
1446 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <4 x float> [[VEC]], i32 [[IDX]]
1447 ; CHECK-NEXT:    ret float [[EXTRACT]]
1449   %extract = extractelement <4 x float> %vec, i32 %idx
1450   ret float %extract
1453 define float @returned_extractelement_index0(<4 x float> nofpclass(nan) %vec) {
1454 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1455 ; CHECK-LABEL: define nofpclass(nan) float @returned_extractelement_index0
1456 ; CHECK-SAME: (<4 x float> nofpclass(nan) [[VEC:%.*]]) #[[ATTR3]] {
1457 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <4 x float> [[VEC]], i32 0
1458 ; CHECK-NEXT:    ret float [[EXTRACT]]
1460   %extract = extractelement <4 x float> %vec, i32 0
1461   ret float %extract
1464 define float @returned_extractelement_index_oob(<4 x float> nofpclass(nan) %vec) {
1465 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1466 ; CHECK-LABEL: define nofpclass(nan) float @returned_extractelement_index_oob
1467 ; CHECK-SAME: (<4 x float> nofpclass(nan) [[VEC:%.*]]) #[[ATTR3]] {
1468 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <4 x float> [[VEC]], i32 5
1469 ; CHECK-NEXT:    ret float [[EXTRACT]]
1471   %extract = extractelement <4 x float> %vec, i32 5
1472   ret float %extract
1475 define float @returned_extractelement_scalable(<vscale x 4 x float> nofpclass(nan) %vec) {
1476 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1477 ; CHECK-LABEL: define float @returned_extractelement_scalable
1478 ; CHECK-SAME: (<vscale x 4 x float> nofpclass(nan) [[VEC:%.*]]) #[[ATTR3]] {
1479 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <vscale x 4 x float> [[VEC]], i32 0
1480 ; CHECK-NEXT:    ret float [[EXTRACT]]
1482   %extract = extractelement <vscale x 4 x float> %vec, i32 0
1483   ret float %extract
1486 define float @returned_extractvalue([4 x float] nofpclass(nan) %array) {
1487 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1488 ; CHECK-LABEL: define nofpclass(nan) float @returned_extractvalue
1489 ; CHECK-SAME: ([4 x float] nofpclass(nan) [[ARRAY:%.*]]) #[[ATTR3]] {
1490 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractvalue [4 x float] [[ARRAY]], 0
1491 ; CHECK-NEXT:    ret float [[EXTRACT]]
1493   %extract = extractvalue [4 x float] %array, 0
1494   ret float %extract
1497 define float @return_nofpclass_freeze_nan_arg(float nofpclass(nan) %arg) {
1498 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1499 ; CHECK-LABEL: define noundef float @return_nofpclass_freeze_nan_arg
1500 ; CHECK-SAME: (float nofpclass(nan) [[ARG:%.*]]) #[[ATTR3]] {
1501 ; CHECK-NEXT:    [[FREEZE:%.*]] = freeze float [[ARG]]
1502 ; CHECK-NEXT:    ret float [[FREEZE]]
1504   %freeze = freeze float %arg
1505   ret float %freeze
1508 define float @return_nofpclass_extractelement_freeze_pinf_arg(<2 x float> nofpclass(pinf) %arg) {
1509 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1510 ; CHECK-LABEL: define noundef float @return_nofpclass_extractelement_freeze_pinf_arg
1511 ; CHECK-SAME: (<2 x float> nofpclass(pinf) [[ARG:%.*]]) #[[ATTR3]] {
1512 ; CHECK-NEXT:    [[FREEZE:%.*]] = freeze <2 x float> [[ARG]]
1513 ; CHECK-NEXT:    [[ELT:%.*]] = extractelement <2 x float> [[FREEZE]], i32 0
1514 ; CHECK-NEXT:    ret float [[ELT]]
1516   %freeze = freeze <2 x float> %arg
1517   %elt = extractelement <2 x float> %freeze, i32 0
1518   ret float %elt
1521 define <4 x float> @insertelement_constant_chain() {
1522 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1523 ; CHECK-LABEL: define nofpclass(nan ninf nzero sub) <4 x float> @insertelement_constant_chain
1524 ; CHECK-SAME: () #[[ATTR3]] {
1525 ; CHECK-NEXT:    [[INS_0:%.*]] = insertelement <4 x float> poison, float 1.000000e+00, i32 0
1526 ; CHECK-NEXT:    [[INS_1:%.*]] = insertelement <4 x float> [[INS_0]], float 0.000000e+00, i32 1
1527 ; CHECK-NEXT:    [[INS_2:%.*]] = insertelement <4 x float> [[INS_1]], float -9.000000e+00, i32 2
1528 ; CHECK-NEXT:    [[INS_3:%.*]] = insertelement <4 x float> [[INS_2]], float 0x7FF0000000000000, i32 3
1529 ; CHECK-NEXT:    ret <4 x float> [[INS_3]]
1531   %ins.0 = insertelement <4 x float> poison, float 1.0, i32 0
1532   %ins.1 = insertelement <4 x float> %ins.0, float 0.0, i32 1
1533   %ins.2 = insertelement <4 x float> %ins.1, float -9.0, i32 2
1534   %ins.3 = insertelement <4 x float> %ins.2, float 0x7FF0000000000000, i32 3
1535   ret <4 x float> %ins.3
1538 define <4 x float> @insertelement_non_constant_chain(i32 %idx) {
1539 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1540 ; CHECK-LABEL: define nofpclass(nan inf nzero sub) <4 x float> @insertelement_non_constant_chain
1541 ; CHECK-SAME: (i32 [[IDX:%.*]]) #[[ATTR3]] {
1542 ; CHECK-NEXT:    [[INS_0:%.*]] = insertelement <4 x float> poison, float 1.000000e+00, i32 0
1543 ; CHECK-NEXT:    [[INS_1:%.*]] = insertelement <4 x float> [[INS_0]], float 0.000000e+00, i32 1
1544 ; CHECK-NEXT:    [[INS_2:%.*]] = insertelement <4 x float> [[INS_1]], float -9.000000e+00, i32 2
1545 ; CHECK-NEXT:    [[INS_3:%.*]] = insertelement <4 x float> [[INS_2]], float 3.000000e+00, i32 3
1546 ; CHECK-NEXT:    [[INS_4:%.*]] = insertelement <4 x float> [[INS_2]], float 4.000000e+00, i32 [[IDX]]
1547 ; CHECK-NEXT:    ret <4 x float> [[INS_4]]
1549   %ins.0 = insertelement <4 x float> poison, float 1.0, i32 0
1550   %ins.1 = insertelement <4 x float> %ins.0, float 0.0, i32 1
1551   %ins.2 = insertelement <4 x float> %ins.1, float -9.0, i32 2
1552   %ins.3 = insertelement <4 x float> %ins.2, float 3.0, i32 3
1553   %ins.4 = insertelement <4 x float> %ins.2, float 4.0, i32 %idx
1554   ret <4 x float> %ins.4
1557 define <vscale x 4 x float> @insertelement_scalable_constant_chain() {
1558 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1559 ; CHECK-LABEL: define <vscale x 4 x float> @insertelement_scalable_constant_chain
1560 ; CHECK-SAME: () #[[ATTR3]] {
1561 ; CHECK-NEXT:    [[INS_0:%.*]] = insertelement <vscale x 4 x float> poison, float 1.000000e+00, i32 0
1562 ; CHECK-NEXT:    [[INS_1:%.*]] = insertelement <vscale x 4 x float> [[INS_0]], float 0.000000e+00, i32 1
1563 ; CHECK-NEXT:    [[INS_2:%.*]] = insertelement <vscale x 4 x float> [[INS_1]], float -9.000000e+00, i32 2
1564 ; CHECK-NEXT:    [[INS_3:%.*]] = insertelement <vscale x 4 x float> [[INS_2]], float 0x7FF0000000000000, i32 3
1565 ; CHECK-NEXT:    ret <vscale x 4 x float> [[INS_3]]
1567   %ins.0 = insertelement <vscale x 4 x float> poison, float 1.0, i32 0
1568   %ins.1 = insertelement <vscale x 4 x float> %ins.0, float 0.0, i32 1
1569   %ins.2 = insertelement <vscale x 4 x float> %ins.1, float -9.0, i32 2
1570   %ins.3 = insertelement <vscale x 4 x float> %ins.2, float 0x7FF0000000000000, i32 3
1571   ret <vscale x 4 x float> %ins.3
1574 define <4 x float> @insertelement_unknown_base(<4 x float> %arg0) {
1575 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1576 ; CHECK-LABEL: define <4 x float> @insertelement_unknown_base
1577 ; CHECK-SAME: (<4 x float> [[ARG0:%.*]]) #[[ATTR3]] {
1578 ; CHECK-NEXT:    [[INSERT:%.*]] = insertelement <4 x float> [[ARG0]], float 0.000000e+00, i32 1
1579 ; CHECK-NEXT:    ret <4 x float> [[INSERT]]
1581   %insert = insertelement <4 x float> %arg0, float 0.0, i32 1
1582   ret <4 x float> %insert
1585 define float @insertelement_extractelement_same(<4 x float> %arg0) {
1586 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1587 ; CHECK-LABEL: define nofpclass(nan inf nzero sub norm) float @insertelement_extractelement_same
1588 ; CHECK-SAME: (<4 x float> [[ARG0:%.*]]) #[[ATTR3]] {
1589 ; CHECK-NEXT:    [[INSERT:%.*]] = insertelement <4 x float> [[ARG0]], float 0.000000e+00, i32 1
1590 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <4 x float> [[INSERT]], i32 1
1591 ; CHECK-NEXT:    ret float [[EXTRACT]]
1593   %insert = insertelement <4 x float> %arg0, float 0.0, i32 1
1594   %extract = extractelement <4 x float> %insert, i32 1
1595   ret float %extract
1598 define float @insertelement_extractelement_different(<4 x float> nofpclass(zero) %arg0) {
1599 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1600 ; CHECK-LABEL: define nofpclass(zero) float @insertelement_extractelement_different
1601 ; CHECK-SAME: (<4 x float> nofpclass(zero) [[ARG0:%.*]]) #[[ATTR3]] {
1602 ; CHECK-NEXT:    [[INSERT:%.*]] = insertelement <4 x float> [[ARG0]], float 0.000000e+00, i32 1
1603 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <4 x float> [[INSERT]], i32 2
1604 ; CHECK-NEXT:    ret float [[EXTRACT]]
1606   %insert = insertelement <4 x float> %arg0, float 0.0, i32 1
1607   %extract = extractelement <4 x float> %insert, i32 2
1608   ret float %extract
1611 define float @insertelement_extractelement_unknown(<4 x float> nofpclass(zero) %arg0, i32 %idx) {
1612 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1613 ; CHECK-LABEL: define nofpclass(nzero) float @insertelement_extractelement_unknown
1614 ; CHECK-SAME: (<4 x float> nofpclass(zero) [[ARG0:%.*]], i32 [[IDX:%.*]]) #[[ATTR3]] {
1615 ; CHECK-NEXT:    [[INSERT:%.*]] = insertelement <4 x float> [[ARG0]], float 0.000000e+00, i32 1
1616 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <4 x float> [[INSERT]], i32 [[IDX]]
1617 ; CHECK-NEXT:    ret float [[EXTRACT]]
1619   %insert = insertelement <4 x float> %arg0, float 0.0, i32 1
1620   %extract = extractelement <4 x float> %insert, i32 %idx
1621   ret float %extract
1624 define <4 x float> @insertelement_index_oob_chain() {
1625 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1626 ; CHECK-LABEL: define nofpclass(nan ninf nzero sub norm) <4 x float> @insertelement_index_oob_chain
1627 ; CHECK-SAME: () #[[ATTR3]] {
1628 ; CHECK-NEXT:    [[INSERT:%.*]] = insertelement <4 x float> zeroinitializer, float 0x7FF0000000000000, i32 4
1629 ; CHECK-NEXT:    ret <4 x float> [[INSERT]]
1631   %insert = insertelement <4 x float> zeroinitializer, float 0x7FF0000000000000, i32 4
1632   ret <4 x float> %insert
1635 define <2 x float> @multiple_extractelement(<4 x float> nofpclass(zero) %arg0) {
1636 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1637 ; CHECK-LABEL: define nofpclass(zero) <2 x float> @multiple_extractelement
1638 ; CHECK-SAME: (<4 x float> nofpclass(zero) [[ARG0:%.*]]) #[[ATTR3]] {
1639 ; CHECK-NEXT:    [[INSERT:%.*]] = insertelement <4 x float> [[ARG0]], float 0.000000e+00, i32 1
1640 ; CHECK-NEXT:    [[EXTRACT2:%.*]] = extractelement <4 x float> [[INSERT]], i32 2
1641 ; CHECK-NEXT:    [[EXTRACT3:%.*]] = extractelement <4 x float> [[INSERT]], i32 3
1642 ; CHECK-NEXT:    [[INS_0:%.*]] = insertelement <2 x float> poison, float [[EXTRACT3]], i32 0
1643 ; CHECK-NEXT:    [[INS_1:%.*]] = insertelement <2 x float> [[INS_0]], float [[EXTRACT2]], i32 1
1644 ; CHECK-NEXT:    ret <2 x float> [[INS_1]]
1646   %insert = insertelement <4 x float> %arg0, float 0.0, i32 1
1647   %extract2 = extractelement <4 x float> %insert, i32 2
1648   %extract3 = extractelement <4 x float> %insert, i32 3
1649   %ins.0 = insertelement <2 x float> poison, float %extract3, i32 0
1650   %ins.1 = insertelement <2 x float> %ins.0, float %extract2, i32 1
1651   ret <2 x float> %ins.1
1654 ; FIXME: Doesn't actually reach computeKnownFPClass
1655 define <4 x float> @shufflevector_constexpr() {
1656 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1657 ; CHECK-LABEL: define <4 x float> @shufflevector_constexpr
1658 ; CHECK-SAME: () #[[ATTR3]] {
1659 ; CHECK-NEXT:    ret <4 x float> <float 1.000000e+00, float bitcast (i32 ptrtoint (ptr @shufflevector_constexpr to i32) to float), float 4.000000e+00, float 0.000000e+00>
1661   ret <4 x float> shufflevector (<2 x float> <float 1.0, float bitcast (i32 ptrtoint (ptr @shufflevector_constexpr to i32) to float)>, <2 x float> <float 4.0, float 0.0>, <4 x i32> <i32 0, i32 1, i32 2, i32 3>)
1664 define <4 x float> @shufflevector_concat_disjoint(<2 x float> nofpclass(nan) %arg0, <2 x float> nofpclass(inf) %arg1) {
1665 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1666 ; CHECK-LABEL: define <4 x float> @shufflevector_concat_disjoint
1667 ; CHECK-SAME: (<2 x float> nofpclass(nan) [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] {
1668 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>
1669 ; CHECK-NEXT:    ret <4 x float> [[SHUFFLE]]
1671   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
1672   ret <4 x float> %shuffle
1675 define <4 x float> @shufflevector_concat_overlap(<2 x float> nofpclass(nan norm psub) %arg0, <2 x float> nofpclass(inf nan sub) %arg1) {
1676 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1677 ; CHECK-LABEL: define nofpclass(nan psub) <4 x float> @shufflevector_concat_overlap
1678 ; CHECK-SAME: (<2 x float> nofpclass(nan psub norm) [[ARG0:%.*]], <2 x float> nofpclass(nan inf sub) [[ARG1:%.*]]) #[[ATTR3]] {
1679 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>
1680 ; CHECK-NEXT:    ret <4 x float> [[SHUFFLE]]
1682   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
1683   ret <4 x float> %shuffle
1686 define <4 x float> @shufflevector_unknown_lhs(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) {
1687 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1688 ; CHECK-LABEL: define <4 x float> @shufflevector_unknown_lhs
1689 ; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] {
1690 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 3, i32 2, i32 1, i32 0>
1691 ; CHECK-NEXT:    ret <4 x float> [[SHUFFLE]]
1693   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
1694   ret <4 x float> %shuffle
1697 define <4 x float> @shufflevector_unknown_rhs(<2 x float> nofpclass(inf) %arg0, <2 x float> %arg1) {
1698 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1699 ; CHECK-LABEL: define <4 x float> @shufflevector_unknown_rhs
1700 ; CHECK-SAME: (<2 x float> nofpclass(inf) [[ARG0:%.*]], <2 x float> [[ARG1:%.*]]) #[[ATTR3]] {
1701 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 3, i32 2, i32 1, i32 0>
1702 ; CHECK-NEXT:    ret <4 x float> [[SHUFFLE]]
1704   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
1705   ret <4 x float> %shuffle
1708 define <4 x float> @shufflevector_unknown_all(<2 x float> %arg0, <2 x float> %arg1) {
1709 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1710 ; CHECK-LABEL: define <4 x float> @shufflevector_unknown_all
1711 ; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> [[ARG1:%.*]]) #[[ATTR3]] {
1712 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 3, i32 2, i32 1, i32 0>
1713 ; CHECK-NEXT:    ret <4 x float> [[SHUFFLE]]
1715   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
1716   ret <4 x float> %shuffle
1719 define <4 x float> @shufflevector_only_demand_lhs(<2 x float> nofpclass(inf) %arg0, <2 x float> %arg1) {
1720 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1721 ; CHECK-LABEL: define nofpclass(inf) <4 x float> @shufflevector_only_demand_lhs
1722 ; CHECK-SAME: (<2 x float> nofpclass(inf) [[ARG0:%.*]], <2 x float> [[ARG1:%.*]]) #[[ATTR3]] {
1723 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 0, i32 1, i32 1, i32 0>
1724 ; CHECK-NEXT:    ret <4 x float> [[SHUFFLE]]
1726   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 0, i32 1, i32 1, i32 0>
1727   ret <4 x float> %shuffle
1730 define <4 x float> @shufflevector_only_demand_rhs(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) {
1731 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1732 ; CHECK-LABEL: define nofpclass(inf) <4 x float> @shufflevector_only_demand_rhs
1733 ; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] {
1734 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 2, i32 3, i32 3, i32 2>
1735 ; CHECK-NEXT:    ret <4 x float> [[SHUFFLE]]
1737   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 2, i32 3, i32 3, i32 2>
1738   ret <4 x float> %shuffle
1741 define <4 x float> @shufflevector_undef_demanded(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) {
1742 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1743 ; CHECK-LABEL: define <4 x float> @shufflevector_undef_demanded
1744 ; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] {
1745 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> poison
1746 ; CHECK-NEXT:    ret <4 x float> [[SHUFFLE]]
1748   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> undef
1749   ret <4 x float> %shuffle
1752 define <4 x float> @shufflevector_zeroinit_demanded(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) {
1753 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1754 ; CHECK-LABEL: define <4 x float> @shufflevector_zeroinit_demanded
1755 ; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] {
1756 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> zeroinitializer
1757 ; CHECK-NEXT:    ret <4 x float> [[SHUFFLE]]
1759   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> zeroinitializer
1760   ret <4 x float> %shuffle
1763 define float @shufflevector_extractelt0(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) {
1764 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1765 ; CHECK-LABEL: define float @shufflevector_extractelt0
1766 ; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] {
1767 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 1, i32 3, i32 0, i32 1>
1768 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <4 x float> [[SHUFFLE]], i32 0
1769 ; CHECK-NEXT:    ret float [[EXTRACT]]
1771   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 1, i32 3, i32 0, i32 1>
1772   %extract = extractelement <4 x float> %shuffle, i32 0
1773   ret float %extract
1776 define float @shufflevector_extractelt1(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) {
1777 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1778 ; CHECK-LABEL: define nofpclass(inf) float @shufflevector_extractelt1
1779 ; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] {
1780 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 1, i32 3, i32 0, i32 1>
1781 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <4 x float> [[SHUFFLE]], i32 1
1782 ; CHECK-NEXT:    ret float [[EXTRACT]]
1784   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 1, i32 3, i32 0, i32 1>
1785   %extract = extractelement <4 x float> %shuffle, i32 1
1786   ret float %extract
1789 define float @shufflevector_extractelt2(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) {
1790 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1791 ; CHECK-LABEL: define float @shufflevector_extractelt2
1792 ; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] {
1793 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 1, i32 3, i32 0, i32 1>
1794 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <4 x float> [[SHUFFLE]], i32 2
1795 ; CHECK-NEXT:    ret float [[EXTRACT]]
1797   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 1, i32 3, i32 0, i32 1>
1798   %extract = extractelement <4 x float> %shuffle, i32 2
1799   ret float %extract
1802 define float @shufflevector_extractelt3(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) {
1803 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1804 ; CHECK-LABEL: define float @shufflevector_extractelt3
1805 ; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] {
1806 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 1, i32 3, i32 0, i32 1>
1807 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <4 x float> [[SHUFFLE]], i32 3
1808 ; CHECK-NEXT:    ret float [[EXTRACT]]
1810   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 1, i32 3, i32 0, i32 1>
1811   %extract = extractelement <4 x float> %shuffle, i32 3
1812   ret float %extract
1815 define float @shufflevector_constantdatavector_demanded0() {
1816 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1817 ; CHECK-LABEL: define nofpclass(nan inf zero sub nnorm) float @shufflevector_constantdatavector_demanded0
1818 ; CHECK-SAME: () #[[ATTR3]] {
1819 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <3 x float> <float 1.000000e+00, float 0x7FF8000000000000, float 0.000000e+00>, <3 x float> poison, <2 x i32> <i32 0, i32 2>
1820 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <2 x float> [[SHUFFLE]], i32 0
1821 ; CHECK-NEXT:    ret float [[EXTRACT]]
1823   %shuffle = shufflevector <3 x float> <float 1.0, float 0x7FF8000000000000, float 0.0>, <3 x float> poison, <2 x i32> <i32 0, i32 2>
1824   %extract = extractelement <2 x float> %shuffle, i32 0
1825   ret float %extract
1828 define float @shufflevector_constantdatavector_demanded1() {
1829 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1830 ; CHECK-LABEL: define nofpclass(nan inf nzero sub norm) float @shufflevector_constantdatavector_demanded1
1831 ; CHECK-SAME: () #[[ATTR3]] {
1832 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <3 x float> <float 1.000000e+00, float 0x7FF8000000000000, float 0.000000e+00>, <3 x float> poison, <2 x i32> <i32 0, i32 2>
1833 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <2 x float> [[SHUFFLE]], i32 1
1834 ; CHECK-NEXT:    ret float [[EXTRACT]]
1836   %shuffle = shufflevector <3 x float> <float 1.0, float 0x7FF8000000000000, float 0.0>, <3 x float> poison, <2 x i32> <i32 0, i32 2>
1837   %extract = extractelement <2 x float> %shuffle, i32 1
1838   ret float %extract
1841 define i32 @fptosi(float nofpclass(inf nan) %arg) {
1842 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1843 ; CHECK-LABEL: define i32 @fptosi
1844 ; CHECK-SAME: (float nofpclass(nan inf) [[ARG:%.*]]) #[[ATTR3]] {
1845 ; CHECK-NEXT:    [[FPTOSI:%.*]] = fptosi float [[ARG]] to i32
1846 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[FPTOSI]], 1
1847 ; CHECK-NEXT:    ret i32 [[ADD]]
1849   %fptosi = fptosi float %arg to i32
1850   %add = add i32 %fptosi, 1
1851   ret i32 %add
1854 define float @fptrunc(double nofpclass(inf nan) %arg) {
1855 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1856 ; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @fptrunc
1857 ; CHECK-SAME: (double nofpclass(nan inf) [[ARG:%.*]]) #[[ATTR3]] {
1858 ; CHECK-NEXT:    [[CAST:%.*]] = fptrunc double [[ARG]] to float
1859 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[CAST]], [[CAST]]
1860 ; CHECK-NEXT:    ret float [[MUL]]
1862   %cast = fptrunc double %arg to float
1863   %mul = fmul float %cast, %cast
1864   ret float %mul
1867 define double @fpext(float nofpclass(inf nan) %arg) {
1868 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1869 ; CHECK-LABEL: define nofpclass(nan ninf nzero nsub nnorm) double @fpext
1870 ; CHECK-SAME: (float nofpclass(nan inf) [[ARG:%.*]]) #[[ATTR3]] {
1871 ; CHECK-NEXT:    [[CAST:%.*]] = fpext float [[ARG]] to double
1872 ; CHECK-NEXT:    [[MUL:%.*]] = fmul double [[CAST]], [[CAST]]
1873 ; CHECK-NEXT:    ret double [[MUL]]
1875   %cast = fpext float %arg to double
1876   %mul = fmul double %cast, %cast
1877   ret double %mul
1880 define float @atomicrmw_fadd(ptr %ptr, float nofpclass(inf nan) %val) {
1881 ; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
1882 ; CHECK-LABEL: define float @atomicrmw_fadd
1883 ; CHECK-SAME: (ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[PTR:%.*]], float nofpclass(nan inf) [[VAL:%.*]]) #[[ATTR6:[0-9]+]] {
1884 ; CHECK-NEXT:    [[RESULT:%.*]] = atomicrmw fadd ptr [[PTR]], float [[VAL]] seq_cst, align 4
1885 ; CHECK-NEXT:    ret float [[RESULT]]
1887   %result = atomicrmw fadd ptr %ptr, float %val seq_cst
1888   ret float %result
1891 define float @load(ptr %ptr, float nofpclass(nan inf) %val) {
1892 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)
1893 ; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @load
1894 ; CHECK-SAME: (ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[PTR:%.*]], float nofpclass(nan inf) [[VAL:%.*]]) #[[ATTR7:[0-9]+]] {
1895 ; CHECK-NEXT:    store float [[VAL]], ptr [[PTR]], align 4
1896 ; CHECK-NEXT:    [[LOAD:%.*]] = load float, ptr [[PTR]], align 4
1897 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[LOAD]], [[LOAD]]
1898 ; CHECK-NEXT:    ret float [[MUL]]
1900   store float %val, ptr %ptr
1901   %load = load float, ptr %ptr
1902   %mul = fmul float %load, %load
1903   ret float %mul
1906 define float @load_atomic(ptr %ptr, float nofpclass(nan inf) %val) {
1907 ; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
1908 ; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @load_atomic
1909 ; CHECK-SAME: (ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[PTR:%.*]], float nofpclass(nan inf) [[VAL:%.*]]) #[[ATTR6]] {
1910 ; CHECK-NEXT:    store atomic float [[VAL]], ptr [[PTR]] seq_cst, align 4
1911 ; CHECK-NEXT:    [[LOAD:%.*]] = load atomic float, ptr [[PTR]] seq_cst, align 4
1912 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[LOAD]], [[LOAD]]
1913 ; CHECK-NEXT:    ret float [[MUL]]
1915   store atomic float %val, ptr %ptr seq_cst, align 4
1916   %load = load atomic float, ptr %ptr seq_cst, align 4
1917   %mul = fmul float %load, %load
1918   ret float %mul
1921 define <8 x float> @shufflevector_shufflevector(<4 x float> nofpclass(inf nan) %arg0, <4 x float> nofpclass(inf nan zero) %arg1) {
1922 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1923 ; CHECK-LABEL: define nofpclass(nan inf) <8 x float> @shufflevector_shufflevector
1924 ; CHECK-SAME: (<4 x float> nofpclass(nan inf) [[ARG0:%.*]], <4 x float> nofpclass(nan inf zero) [[ARG1:%.*]]) #[[ATTR3]] {
1925 ; CHECK-NEXT:    [[SHUFFLE0:%.*]] = shufflevector <4 x float> [[ARG0]], <4 x float> [[ARG0]], <4 x i32> <i32 3, i32 2, i32 1, i32 0>
1926 ; CHECK-NEXT:    [[SHUFFLE1:%.*]] = shufflevector <4 x float> [[ARG1]], <4 x float> [[ARG1]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>
1927 ; CHECK-NEXT:    [[SHUFFLE2:%.*]] = shufflevector <4 x float> [[SHUFFLE0]], <4 x float> [[SHUFFLE1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
1928 ; CHECK-NEXT:    ret <8 x float> [[SHUFFLE2]]
1930   %shuffle0 = shufflevector <4 x float> %arg0, <4 x float> %arg0, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
1931   %shuffle1 = shufflevector <4 x float> %arg1, <4 x float> %arg1, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
1932   %shuffle2 = shufflevector <4 x float> %shuffle0, <4 x float> %shuffle1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
1933   ret <8 x float> %shuffle2
1936 define float @constrained_sitofp(i32 %arg) strictfp {
1937 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite)
1938 ; CHECK-LABEL: define nofpclass(nan nzero sub) float @constrained_sitofp
1939 ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR8:[0-9]+]] {
1940 ; CHECK-NEXT:    [[VAL:%.*]] = call nofpclass(nan nzero sub) float @llvm.experimental.constrained.sitofp.f32.i32(i32 [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR20]]
1941 ; CHECK-NEXT:    ret float [[VAL]]
1943   %val = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %arg, metadata !"round.dynamic", metadata !"fpexcept.strict")
1944   ret float %val
1947 define float @constrained_uitofp(i32 %arg) strictfp {
1948 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite)
1949 ; CHECK-LABEL: define nofpclass(nan ninf nzero sub nnorm) float @constrained_uitofp
1950 ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR8]] {
1951 ; CHECK-NEXT:    [[VAL:%.*]] = call nofpclass(nan ninf nzero sub nnorm) float @llvm.experimental.constrained.uitofp.f32.i32(i32 [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR20]]
1952 ; CHECK-NEXT:    ret float [[VAL]]
1954   %val = call float @llvm.experimental.constrained.uitofp.f32.i32(i32 %arg, metadata !"round.dynamic", metadata !"fpexcept.strict")
1955   ret float %val
1958 define float @fadd_p0(float %arg0) {
1959 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1960 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_p0
1961 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR3]] {
1962 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], 0.000000e+00
1963 ; CHECK-NEXT:    ret float [[ADD]]
1965   %add = fadd float %arg0, 0.0
1966   ret float %add
1969 define float @fadd_n0(float %arg0) {
1970 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1971 ; CHECK-LABEL: define float @fadd_n0
1972 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR3]] {
1973 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], -0.000000e+00
1974 ; CHECK-NEXT:    ret float [[ADD]]
1976   %add = fadd float %arg0, -0.0
1977   ret float %add
1980 define float @fsub_p0(float %arg0) {
1981 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1982 ; CHECK-LABEL: define float @fsub_p0
1983 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR3]] {
1984 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[ARG0]], 0.000000e+00
1985 ; CHECK-NEXT:    ret float [[SUB]]
1987   %sub = fsub float %arg0, 0.0
1988   ret float %sub
1991 define float @fsub_n0(float %arg0) {
1992 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1993 ; CHECK-LABEL: define nofpclass(nzero) float @fsub_n0
1994 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR3]] {
1995 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[ARG0]], -0.000000e+00
1996 ; CHECK-NEXT:    ret float [[SUB]]
1998   %sub = fsub float %arg0, -0.0
1999   ret float %sub
2002 define float @fsub_p0_commute(float %arg0) {
2003 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2004 ; CHECK-LABEL: define nofpclass(nzero) float @fsub_p0_commute
2005 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR3]] {
2006 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float 0.000000e+00, [[ARG0]]
2007 ; CHECK-NEXT:    ret float [[SUB]]
2009   %sub = fsub float 0.0, %arg0
2010   ret float %sub
2013 define float @fsub_n0_commute(float %arg0) {
2014 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2015 ; CHECK-LABEL: define float @fsub_n0_commute
2016 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR3]] {
2017 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float -0.000000e+00, [[ARG0]]
2018 ; CHECK-NEXT:    ret float [[SUB]]
2020   %sub = fsub float -0.0, %arg0
2021   ret float %sub
2024 define float @fadd_p0_ftz_daz(float %arg0) #3 {
2025 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2026 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_p0_ftz_daz
2027 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR9:[0-9]+]] {
2028 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], 0.000000e+00
2029 ; CHECK-NEXT:    ret float [[ADD]]
2031   %add = fadd float %arg0, 0.0
2032   ret float %add
2035 define float @fadd_n0_ftz_daz(float %arg0) #0 {
2036 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2037 ; CHECK-LABEL: define float @fadd_n0_ftz_daz
2038 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR10:[0-9]+]] {
2039 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], -0.000000e+00
2040 ; CHECK-NEXT:    ret float [[ADD]]
2042   %add = fadd float %arg0, -0.0
2043   ret float %add
2046 define float @fsub_p0_ftz_daz(float %arg0) #0 {
2047 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2048 ; CHECK-LABEL: define float @fsub_p0_ftz_daz
2049 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR10]] {
2050 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[ARG0]], 0.000000e+00
2051 ; CHECK-NEXT:    ret float [[SUB]]
2053   %sub = fsub float %arg0, 0.0
2054   ret float %sub
2057 define float @fsub_n0_ftz_daz(float %arg0) #0 {
2058 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2059 ; CHECK-LABEL: define float @fsub_n0_ftz_daz
2060 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR10]] {
2061 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[ARG0]], -0.000000e+00
2062 ; CHECK-NEXT:    ret float [[SUB]]
2064   %sub = fsub float %arg0, -0.0
2065   ret float %sub
2068 define float @fsub_p0_commute_ftz_daz(float %arg0) #0 {
2069 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2070 ; CHECK-LABEL: define float @fsub_p0_commute_ftz_daz
2071 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR10]] {
2072 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float 0.000000e+00, [[ARG0]]
2073 ; CHECK-NEXT:    ret float [[SUB]]
2075   %sub = fsub float 0.0, %arg0
2076   ret float %sub
2079 define float @fsub_n0_commute_ftz_daz(float %arg0) #0 {
2080 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2081 ; CHECK-LABEL: define float @fsub_n0_commute_ftz_daz
2082 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR10]] {
2083 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float -0.000000e+00, [[ARG0]]
2084 ; CHECK-NEXT:    ret float [[SUB]]
2086   %sub = fsub float -0.0, %arg0
2087   ret float %sub
2090 define float @fadd_p0_ieee_daz(float %arg0) #2 {
2091 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2092 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_p0_ieee_daz
2093 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR11:[0-9]+]] {
2094 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], 0.000000e+00
2095 ; CHECK-NEXT:    ret float [[ADD]]
2097   %add = fadd float %arg0, 0.0
2098   ret float %add
2101 define float @fadd_p0_dapz_ieee(float %arg0) #4 {
2102 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2103 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_p0_dapz_ieee
2104 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR12:[0-9]+]] {
2105 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], 0.000000e+00
2106 ; CHECK-NEXT:    ret float [[ADD]]
2108   %add = fadd float %arg0, 0.0
2109   ret float %add
2112 define float @fadd_n0_ieee_daz(float %arg0) #2 {
2113 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2114 ; CHECK-LABEL: define float @fadd_n0_ieee_daz
2115 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR11]] {
2116 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], -0.000000e+00
2117 ; CHECK-NEXT:    ret float [[ADD]]
2119   %add = fadd float %arg0, -0.0
2120   ret float %add
2123 define float @fsub_p0_ieee_daz(float %arg0) #2 {
2124 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2125 ; CHECK-LABEL: define float @fsub_p0_ieee_daz
2126 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR11]] {
2127 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[ARG0]], 0.000000e+00
2128 ; CHECK-NEXT:    ret float [[SUB]]
2130   %sub = fsub float %arg0, 0.0
2131   ret float %sub
2134 define float @fsub_n0_ieee_daz(float %arg0) #2 {
2135 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2136 ; CHECK-LABEL: define nofpclass(nzero) float @fsub_n0_ieee_daz
2137 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR11]] {
2138 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[ARG0]], -0.000000e+00
2139 ; CHECK-NEXT:    ret float [[SUB]]
2141   %sub = fsub float %arg0, -0.0
2142   ret float %sub
2145 define float @fsub_p0_commute_ieee_daz(float %arg0) #2 {
2146 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2147 ; CHECK-LABEL: define nofpclass(nzero) float @fsub_p0_commute_ieee_daz
2148 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR11]] {
2149 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float 0.000000e+00, [[ARG0]]
2150 ; CHECK-NEXT:    ret float [[SUB]]
2152   %sub = fsub float 0.0, %arg0
2153   ret float %sub
2156 define float @fsub_n0_commute_ieee_daz(float %arg0) #1 {
2157 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2158 ; CHECK-LABEL: define float @fsub_n0_commute_ieee_daz
2159 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR13:[0-9]+]] {
2160 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float -0.000000e+00, [[ARG0]]
2161 ; CHECK-NEXT:    ret float [[SUB]]
2163   %sub = fsub float -0.0, %arg0
2164   ret float %sub
2167 define float @fadd_never_negzero_or_negsub(float nofpclass(nzero nsub) %a, float nofpclass(nzero nsub) %b) {
2168 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2169 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_negsub
2170 ; CHECK-SAME: (float nofpclass(nzero nsub) [[A:%.*]], float nofpclass(nzero nsub) [[B:%.*]]) #[[ATTR3]] {
2171 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[A]], [[B]]
2172 ; CHECK-NEXT:    ret float [[ADD]]
2174   %add = fadd float %a, %b
2175   ret float %add
2178 define float @fadd_never_negzero_or_negsub_daz(float nofpclass(nzero nsub) %a, float nofpclass(nzero nsub) %b) #2 {
2179 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2180 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_negsub_daz
2181 ; CHECK-SAME: (float nofpclass(nzero nsub) [[A:%.*]], float nofpclass(nzero nsub) [[B:%.*]]) #[[ATTR11]] {
2182 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[A]], [[B]]
2183 ; CHECK-NEXT:    ret float [[ADD]]
2185   %add = fadd float %a, %b
2186   ret float %add
2189 define float @fadd_never_negzero_or_negsub_dapz(float nofpclass(nzero nsub) %a, float nofpclass(nzero nsub) %b) #5 {
2190 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2191 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_negsub_dapz
2192 ; CHECK-SAME: (float nofpclass(nzero nsub) [[A:%.*]], float nofpclass(nzero nsub) [[B:%.*]]) #[[ATTR14:[0-9]+]] {
2193 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[A]], [[B]]
2194 ; CHECK-NEXT:    ret float [[ADD]]
2196   %add = fadd float %a, %b
2197   ret float %add
2200 define float @fadd_never_negzero_or_possub(float nofpclass(nzero psub) %a, float nofpclass(nzero psub) %b) {
2201 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2202 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_possub
2203 ; CHECK-SAME: (float nofpclass(nzero psub) [[A:%.*]], float nofpclass(nzero psub) [[B:%.*]]) #[[ATTR3]] {
2204 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[A]], [[B]]
2205 ; CHECK-NEXT:    ret float [[ADD]]
2207   %add = fadd float %a, %b
2208   ret float %add
2211 define float @fadd_never_negzero_or_possub_daz(float nofpclass(nzero psub) %a, float nofpclass(nzero psub) %b) #2 {
2212 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2213 ; CHECK-LABEL: define float @fadd_never_negzero_or_possub_daz
2214 ; CHECK-SAME: (float nofpclass(nzero psub) [[A:%.*]], float nofpclass(nzero psub) [[B:%.*]]) #[[ATTR11]] {
2215 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[A]], [[B]]
2216 ; CHECK-NEXT:    ret float [[ADD]]
2218   %add = fadd float %a, %b
2219   ret float %add
2222 define float @fadd_never_negzero_or_possub_dapz(float nofpclass(nzero psub) %a, float nofpclass(nzero psub) %b) #5 {
2223 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2224 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_possub_dapz
2225 ; CHECK-SAME: (float nofpclass(nzero psub) [[A:%.*]], float nofpclass(nzero psub) [[B:%.*]]) #[[ATTR14]] {
2226 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[A]], [[B]]
2227 ; CHECK-NEXT:    ret float [[ADD]]
2229   %add = fadd float %a, %b
2230   ret float %add
2233 define float @fadd_never_negzero_or_sub_daz(float nofpclass(nzero sub) %a, float nofpclass(nzero sub) %b) #2 {
2234 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2235 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_sub_daz
2236 ; CHECK-SAME: (float nofpclass(nzero sub) [[A:%.*]], float nofpclass(nzero sub) [[B:%.*]]) #[[ATTR11]] {
2237 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[A]], [[B]]
2238 ; CHECK-NEXT:    ret float [[ADD]]
2240   %add = fadd float %a, %b
2241   ret float %add
2244 define float @fadd_never_negzero_or_sub_dapz(float nofpclass(nzero sub) %a, float nofpclass(nzero sub) %b) #5 {
2245 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2246 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_sub_dapz
2247 ; CHECK-SAME: (float nofpclass(nzero sub) [[A:%.*]], float nofpclass(nzero sub) [[B:%.*]]) #[[ATTR14]] {
2248 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[A]], [[B]]
2249 ; CHECK-NEXT:    ret float [[ADD]]
2251   %add = fadd float %a, %b
2252   ret float %add
2255 define float @fadd_known_positive_lhs(float nofpclass(ninf nsub nnorm) %arg0, float %arg1) {
2256 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2257 ; CHECK-LABEL: define float @fadd_known_positive_lhs
2258 ; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR3]] {
2259 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2260 ; CHECK-NEXT:    ret float [[ADD]]
2262   %add = fadd float %arg0, %arg1
2263   ret float %add
2266 define float @fadd_known_positive_rhs(float %arg0, float nofpclass(ninf nsub nnorm) %arg1) {
2267 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2268 ; CHECK-LABEL: define float @fadd_known_positive_rhs
2269 ; CHECK-SAME: (float [[ARG0:%.*]], float nofpclass(ninf nsub nnorm) [[ARG1:%.*]]) #[[ATTR3]] {
2270 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2271 ; CHECK-NEXT:    ret float [[ADD]]
2273   %add = fadd float %arg0, %arg1
2274   ret float %add
2277 define float @fadd_known_positive(float nofpclass(ninf nsub nnorm) %arg0, float nofpclass(ninf nsub nnorm) %arg1) {
2278 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2279 ; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @fadd_known_positive
2280 ; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nsub nnorm) [[ARG1:%.*]]) #[[ATTR3]] {
2281 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2282 ; CHECK-NEXT:    ret float [[ADD]]
2284   %add = fadd float %arg0, %arg1
2285   ret float %add
2288 define float @fadd_known_positive_daz(float nofpclass(ninf nsub nnorm) %arg0, float nofpclass(ninf nsub nnorm) %arg1) #0 {
2289 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2290 ; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @fadd_known_positive_daz
2291 ; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nsub nnorm) [[ARG1:%.*]]) #[[ATTR10]] {
2292 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2293 ; CHECK-NEXT:    ret float [[ADD]]
2295   %add = fadd float %arg0, %arg1
2296   ret float %add
2299 define float @fadd_known_positive_nzero_lhs(float nofpclass(ninf nsub nnorm nzero) %arg0, float nofpclass(ninf nsub nnorm) %arg1) {
2300 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2301 ; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @fadd_known_positive_nzero_lhs
2302 ; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nsub nnorm) [[ARG1:%.*]]) #[[ATTR3]] {
2303 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2304 ; CHECK-NEXT:    ret float [[ADD]]
2306   %add = fadd float %arg0, %arg1
2307   ret float %add
2310 define float @fadd_known_positive_nzero_rhs(float nofpclass(ninf nsub nnorm) %arg0, float nofpclass(ninf nsub nnorm nzero) %arg1) {
2311 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2312 ; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @fadd_known_positive_nzero_rhs
2313 ; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nsub nnorm) [[ARG1:%.*]]) #[[ATTR3]] {
2314 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2315 ; CHECK-NEXT:    ret float [[ADD]]
2317   %add = fadd float %arg0, %arg1
2318   ret float %add
2321 define float @fadd_known_positive_nzero(float nofpclass(ninf nsub nnorm nzero) %arg0, float nofpclass(ninf nsub nnorm nzero) %arg1) {
2322 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2323 ; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @fadd_known_positive_nzero
2324 ; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nsub nnorm) [[ARG1:%.*]]) #[[ATTR3]] {
2325 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2326 ; CHECK-NEXT:    ret float [[ADD]]
2328   %add = fadd float %arg0, %arg1
2329   ret float %add
2332 define float @fadd_known_positive_nzero_ftz_daz(float nofpclass(ninf nsub nnorm nzero) %arg0, float nofpclass(ninf nsub nnorm nzero) %arg1) #0 {
2333 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2334 ; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @fadd_known_positive_nzero_ftz_daz
2335 ; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nsub nnorm) [[ARG1:%.*]]) #[[ATTR10]] {
2336 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2337 ; CHECK-NEXT:    ret float [[ADD]]
2339   %add = fadd float %arg0, %arg1
2340   ret float %add
2343 define float @fadd_known_positive_nzero_ftz(float nofpclass(ninf nsub nnorm nzero) %arg0, float nofpclass(ninf nsub nnorm nzero) %arg1) #1 {
2344 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2345 ; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @fadd_known_positive_nzero_ftz
2346 ; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nsub nnorm) [[ARG1:%.*]]) #[[ATTR13]] {
2347 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2348 ; CHECK-NEXT:    ret float [[ADD]]
2350   %add = fadd float %arg0, %arg1
2351   ret float %add
2354 define float @fadd_known_positive_nzero_daz(float nofpclass(ninf nsub nnorm nzero) %arg0, float nofpclass(ninf nsub nnorm nzero) %arg1) #2 {
2355 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2356 ; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @fadd_known_positive_nzero_daz
2357 ; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nsub nnorm) [[ARG1:%.*]]) #[[ATTR11]] {
2358 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2359 ; CHECK-NEXT:    ret float [[ADD]]
2361   %add = fadd float %arg0, %arg1
2362   ret float %add
2365 define float @fadd_known_positive_normal(float nofpclass(ninf nnorm nzero) %arg0, float nofpclass(ninf nnorm nzero) %arg1) {
2366 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2367 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_known_positive_normal
2368 ; CHECK-SAME: (float nofpclass(ninf nzero nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nnorm) [[ARG1:%.*]]) #[[ATTR3]] {
2369 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2370 ; CHECK-NEXT:    ret float [[ADD]]
2372   %add = fadd float %arg0, %arg1
2373   ret float %add
2376 define float @fadd_known_positive_normal_daz(float nofpclass(ninf nnorm nzero) %arg0, float nofpclass(ninf nnorm nzero) %arg1) #0 {
2377 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2378 ; CHECK-LABEL: define float @fadd_known_positive_normal_daz
2379 ; CHECK-SAME: (float nofpclass(ninf nzero nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nnorm) [[ARG1:%.*]]) #[[ATTR10]] {
2380 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2381 ; CHECK-NEXT:    ret float [[ADD]]
2383   %add = fadd float %arg0, %arg1
2384   ret float %add
2387 define float @fadd_known_positive_normal_except0_daz(float nofpclass(ninf nnorm) %arg0, float nofpclass(ninf nnorm) %arg1) #0 {
2388 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2389 ; CHECK-LABEL: define float @fadd_known_positive_normal_except0_daz
2390 ; CHECK-SAME: (float nofpclass(ninf nnorm) [[ARG0:%.*]], float nofpclass(ninf nnorm) [[ARG1:%.*]]) #[[ATTR10]] {
2391 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2392 ; CHECK-NEXT:    ret float [[ADD]]
2394   %add = fadd float %arg0, %arg1
2395   ret float %add
2398 define float @fadd_known_positive_normal_dapz(float nofpclass(ninf nnorm nzero) %arg0, float nofpclass(ninf nnorm nzero) %arg1) #3 {
2399 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2400 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_known_positive_normal_dapz
2401 ; CHECK-SAME: (float nofpclass(ninf nzero nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nnorm) [[ARG1:%.*]]) #[[ATTR9]] {
2402 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2403 ; CHECK-NEXT:    ret float [[ADD]]
2405   %add = fadd float %arg0, %arg1
2406   ret float %add
2409 define internal float @returns_fence(float %arg) {
2410 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2411 ; TUNIT-LABEL: define internal float @returns_fence
2412 ; TUNIT-SAME: (float nofpclass(nan inf) [[ARG:%.*]]) #[[ATTR3]] {
2413 ; TUNIT-NEXT:    [[RET:%.*]] = call float @llvm.arithmetic.fence.f32(float nofpclass(inf) [[ARG]]) #[[ATTR22]]
2414 ; TUNIT-NEXT:    ret float [[RET]]
2416 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2417 ; CGSCC-LABEL: define internal float @returns_fence
2418 ; CGSCC-SAME: (float nofpclass(nan inf) [[ARG:%.*]]) #[[ATTR3]] {
2419 ; CGSCC-NEXT:    [[RET:%.*]] = call float @llvm.arithmetic.fence.f32(float nofpclass(nan inf) [[ARG]]) #[[ATTR19]]
2420 ; CGSCC-NEXT:    ret float [[RET]]
2422   %ret = call float @llvm.arithmetic.fence.f32(float %arg)
2423   ret float %ret
2426 ; Check that the func0 callsite is marked with both no inf and no nan
2427 define internal float @refine_callsite_attribute(float nofpclass(inf) %arg) {
2428 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2429 ; TUNIT-LABEL: define internal float @refine_callsite_attribute
2430 ; TUNIT-SAME: (float nofpclass(nan inf) [[ARG:%.*]]) #[[ATTR3]] {
2431 ; TUNIT-NEXT:    [[FUNC0:%.*]] = call float @returns_fence(float nofpclass(nan inf) [[ARG]]) #[[ATTR19]]
2432 ; TUNIT-NEXT:    [[RET:%.*]] = call float @llvm.arithmetic.fence.f32(float [[FUNC0]]) #[[ATTR22]]
2433 ; TUNIT-NEXT:    ret float [[RET]]
2435 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
2436 ; CGSCC-LABEL: define internal float @refine_callsite_attribute
2437 ; CGSCC-SAME: (float nofpclass(nan inf) [[ARG:%.*]]) #[[ATTR4]] {
2438 ; CGSCC-NEXT:    [[FUNC0:%.*]] = call float @returns_fence(float nofpclass(nan inf) [[ARG]]) #[[ATTR19]]
2439 ; CGSCC-NEXT:    [[RET:%.*]] = call float @llvm.arithmetic.fence.f32(float [[FUNC0]]) #[[ATTR19]]
2440 ; CGSCC-NEXT:    ret float [[RET]]
2442   %func0 = call float @returns_fence(float nofpclass(nan) %arg)
2443   %ret = call float @llvm.arithmetic.fence.f32(float %func0)
2444   ret float %ret
2447 define float @user(float %arg) {
2448 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2449 ; TUNIT-LABEL: define float @user
2450 ; TUNIT-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR3]] {
2451 ; TUNIT-NEXT:    [[FUNC1:%.*]] = call float @refine_callsite_attribute(float nofpclass(inf) [[ARG]]) #[[ATTR19]]
2452 ; TUNIT-NEXT:    ret float [[FUNC1]]
2454 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
2455 ; CGSCC-LABEL: define float @user
2456 ; CGSCC-SAME: (float nofpclass(nan inf) [[ARG:%.*]]) #[[ATTR4]] {
2457 ; CGSCC-NEXT:    [[FUNC1:%.*]] = call float @refine_callsite_attribute(float nofpclass(nan inf) [[ARG]]) #[[ATTR19]]
2458 ; CGSCC-NEXT:    ret float [[FUNC1]]
2460   %func1 = call float @refine_callsite_attribute(float %arg)
2461   ret float %func1
2464 ; value is passed through memory
2465 define internal float @through_memory0(ptr %ptr.arg) {
2466 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2467 ; CGSCC-LABEL: define internal float @through_memory0
2468 ; CGSCC-SAME: (float [[TMP0:%.*]]) #[[ATTR3]] {
2469 ; CGSCC-NEXT:    [[PTR_ARG_PRIV:%.*]] = alloca float, align 4
2470 ; CGSCC-NEXT:    store float [[TMP0]], ptr [[PTR_ARG_PRIV]], align 4
2471 ; CGSCC-NEXT:    [[LOAD:%.*]] = load float, ptr [[PTR_ARG_PRIV]], align 4
2472 ; CGSCC-NEXT:    ret float [[LOAD]]
2474   %load = load float, ptr %ptr.arg
2475   ret float %load
2478 ; value is passed through memory and goes through an inferrable FP user
2479 define internal float @through_memory1(ptr %ptr.arg) {
2480 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2481 ; TUNIT-LABEL: define internal float @through_memory1
2482 ; TUNIT-SAME: (float [[TMP0:%.*]]) #[[ATTR3]] {
2483 ; TUNIT-NEXT:    [[PTR_ARG_PRIV:%.*]] = alloca float, align 4
2484 ; TUNIT-NEXT:    store float [[TMP0]], ptr [[PTR_ARG_PRIV]], align 4
2485 ; TUNIT-NEXT:    [[LOAD:%.*]] = load float, ptr [[PTR_ARG_PRIV]], align 4
2486 ; TUNIT-NEXT:    [[CALL:%.*]] = call float @llvm.arithmetic.fence.f32(float [[LOAD]]) #[[ATTR22]]
2487 ; TUNIT-NEXT:    ret float [[CALL]]
2489 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2490 ; CGSCC-LABEL: define internal float @through_memory1
2491 ; CGSCC-SAME: (float [[TMP0:%.*]]) #[[ATTR3]] {
2492 ; CGSCC-NEXT:    [[PTR_ARG_PRIV:%.*]] = alloca float, align 4
2493 ; CGSCC-NEXT:    store float [[TMP0]], ptr [[PTR_ARG_PRIV]], align 4
2494 ; CGSCC-NEXT:    [[LOAD:%.*]] = load float, ptr [[PTR_ARG_PRIV]], align 4
2495 ; CGSCC-NEXT:    [[CALL:%.*]] = call float @llvm.arithmetic.fence.f32(float [[LOAD]]) #[[ATTR19]]
2496 ; CGSCC-NEXT:    ret float [[CALL]]
2498   %load = load float, ptr %ptr.arg
2499   %call = call float @llvm.arithmetic.fence.f32(float %load)
2500   ret float %call
2503 ; value is passed through memory and goes through an uninferrable FP user
2504 define internal float @through_memory2(ptr %ptr.arg) {
2505 ; CHECK: Function Attrs: memory(readwrite, argmem: none)
2506 ; CHECK-LABEL: define internal float @through_memory2
2507 ; CHECK-SAME: (float [[TMP0:%.*]]) #[[ATTR15:[0-9]+]] {
2508 ; CHECK-NEXT:    [[PTR_ARG_PRIV:%.*]] = alloca float, align 4
2509 ; CHECK-NEXT:    store float [[TMP0]], ptr [[PTR_ARG_PRIV]], align 4
2510 ; CHECK-NEXT:    [[LOAD:%.*]] = load float, ptr [[PTR_ARG_PRIV]], align 4
2511 ; CHECK-NEXT:    [[CALL:%.*]] = call float @extern.f32(float [[LOAD]])
2512 ; CHECK-NEXT:    ret float [[CALL]]
2514   %load = load float, ptr %ptr.arg
2515   %call = call float @extern.f32(float %load)
2516   ret float %call
2519 define float @call_through_memory0(float nofpclass(nan) %val) {
2520 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2521 ; TUNIT-LABEL: define nofpclass(nan) float @call_through_memory0
2522 ; TUNIT-SAME: (float returned nofpclass(nan) [[VAL:%.*]]) #[[ATTR3]] {
2523 ; TUNIT-NEXT:    [[ALLOCA:%.*]] = alloca float, align 4
2524 ; TUNIT-NEXT:    store float [[VAL]], ptr [[ALLOCA]], align 4
2525 ; TUNIT-NEXT:    ret float [[VAL]]
2527 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
2528 ; CGSCC-LABEL: define float @call_through_memory0
2529 ; CGSCC-SAME: (float nofpclass(nan) [[VAL:%.*]]) #[[ATTR4]] {
2530 ; CGSCC-NEXT:    [[ALLOCA:%.*]] = alloca float, align 4
2531 ; CGSCC-NEXT:    store float [[VAL]], ptr [[ALLOCA]], align 4
2532 ; CGSCC-NEXT:    [[THROUGH_MEMORY:%.*]] = call float @through_memory0(float nofpclass(nan) [[VAL]]) #[[ATTR19]]
2533 ; CGSCC-NEXT:    ret float [[THROUGH_MEMORY]]
2535   %alloca = alloca float
2536   store float %val, ptr %alloca
2537   %through_memory = call float @through_memory0(ptr %alloca)
2538   ret float %through_memory
2541 define float @call_through_memory1(float nofpclass(nan) %val) {
2542 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2543 ; TUNIT-LABEL: define float @call_through_memory1
2544 ; TUNIT-SAME: (float nofpclass(nan) [[VAL:%.*]]) #[[ATTR3]] {
2545 ; TUNIT-NEXT:    [[ALLOCA:%.*]] = alloca float, align 4
2546 ; TUNIT-NEXT:    store float [[VAL]], ptr [[ALLOCA]], align 4
2547 ; TUNIT-NEXT:    [[TMP1:%.*]] = load float, ptr [[ALLOCA]], align 4
2548 ; TUNIT-NEXT:    [[THROUGH_MEMORY:%.*]] = call float @through_memory1(float [[TMP1]]) #[[ATTR21]]
2549 ; TUNIT-NEXT:    ret float [[THROUGH_MEMORY]]
2551 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
2552 ; CGSCC-LABEL: define float @call_through_memory1
2553 ; CGSCC-SAME: (float nofpclass(nan) [[VAL:%.*]]) #[[ATTR4]] {
2554 ; CGSCC-NEXT:    [[ALLOCA:%.*]] = alloca float, align 4
2555 ; CGSCC-NEXT:    store float [[VAL]], ptr [[ALLOCA]], align 4
2556 ; CGSCC-NEXT:    [[THROUGH_MEMORY:%.*]] = call float @through_memory1(float nofpclass(nan) [[VAL]]) #[[ATTR19]]
2557 ; CGSCC-NEXT:    ret float [[THROUGH_MEMORY]]
2559   %alloca = alloca float
2560   store float %val, ptr %alloca
2561   %through_memory = call float @through_memory1(ptr %alloca)
2562   ret float %through_memory
2565 define float @call_through_memory2(float nofpclass(nan) %val) {
2566 ; TUNIT-LABEL: define float @call_through_memory2
2567 ; TUNIT-SAME: (float nofpclass(nan) [[VAL:%.*]]) {
2568 ; TUNIT-NEXT:    [[ALLOCA:%.*]] = alloca float, align 4
2569 ; TUNIT-NEXT:    store float [[VAL]], ptr [[ALLOCA]], align 4
2570 ; TUNIT-NEXT:    [[TMP1:%.*]] = load float, ptr [[ALLOCA]], align 4
2571 ; TUNIT-NEXT:    [[THROUGH_MEMORY:%.*]] = call float @through_memory2(float [[TMP1]])
2572 ; TUNIT-NEXT:    ret float [[THROUGH_MEMORY]]
2574 ; CGSCC-LABEL: define float @call_through_memory2
2575 ; CGSCC-SAME: (float nofpclass(nan) [[VAL:%.*]]) {
2576 ; CGSCC-NEXT:    [[ALLOCA:%.*]] = alloca float, align 4
2577 ; CGSCC-NEXT:    store float [[VAL]], ptr [[ALLOCA]], align 4
2578 ; CGSCC-NEXT:    [[THROUGH_MEMORY:%.*]] = call float @through_memory2(float nofpclass(nan) [[VAL]])
2579 ; CGSCC-NEXT:    ret float [[THROUGH_MEMORY]]
2581   %alloca = alloca float
2582   store float %val, ptr %alloca
2583   %through_memory = call float @through_memory2(ptr %alloca)
2584   ret float %through_memory
2587 define amdgpu_kernel void @fast_pow_kernel(ptr addrspace(1) nocapture noundef writeonly align 4 %out, ptr addrspace(1) nocapture noundef readonly align 4 %in1, ptr addrspace(1) nocapture noundef readonly align 4 %in2)  {
2588 ; CHECK-LABEL: define amdgpu_kernel void @fast_pow_kernel
2589 ; CHECK-SAME: (ptr addrspace(1) nocapture nofree noundef writeonly align 4 [[OUT:%.*]], ptr addrspace(1) nocapture nofree noundef readonly align 4 [[IN1:%.*]], ptr addrspace(1) nocapture nofree noundef readonly align 4 [[IN2:%.*]]) {
2590 ; CHECK-NEXT:  entry:
2591 ; CHECK-NEXT:    [[CALL:%.*]] = tail call i64 @_Z13get_global_idj(i32 noundef 0)
2592 ; CHECK-NEXT:    [[SEXT:%.*]] = shl i64 [[CALL]], 32
2593 ; CHECK-NEXT:    [[IDXPROM:%.*]] = ashr exact i64 [[SEXT]], 32
2594 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr addrspace(1) [[IN1]], i64 [[IDXPROM]]
2595 ; CHECK-NEXT:    [[I:%.*]] = load float, ptr addrspace(1) [[ARRAYIDX]], align 4
2596 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr addrspace(1) [[IN2]], i64 [[IDXPROM]]
2597 ; CHECK-NEXT:    [[I1:%.*]] = load float, ptr addrspace(1) [[ARRAYIDX2]], align 4
2598 ; CHECK-NEXT:    [[CALL3:%.*]] = tail call reassoc nnan ninf nsz arcp afn nofpclass(nan inf) float @pow_wrapper(float noundef nofpclass(nan inf) [[I]], float noundef nofpclass(nan inf) [[I1]])
2599 ; CHECK-NEXT:    [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr addrspace(1) [[OUT]], i64 [[IDXPROM]]
2600 ; CHECK-NEXT:    store float [[CALL3]], ptr addrspace(1) [[ARRAYIDX5]], align 4
2601 ; CHECK-NEXT:    ret void
2603 entry:
2604   %call = tail call i64 @_Z13get_global_idj(i32 noundef 0)
2605   %sext = shl i64 %call, 32
2606   %idxprom = ashr exact i64 %sext, 32
2607   %arrayidx = getelementptr inbounds float, ptr addrspace(1) %in1, i64 %idxprom
2608   %i = load float, ptr addrspace(1) %arrayidx, align 4
2609   %arrayidx2 = getelementptr inbounds float, ptr addrspace(1) %in2, i64 %idxprom
2610   %i1 = load float, ptr addrspace(1) %arrayidx2, align 4
2611   %call3 = tail call reassoc nnan ninf nsz arcp afn nofpclass(nan inf) float @pow_wrapper(float noundef nofpclass(nan inf) %i, float noundef nofpclass(nan inf) %i1)
2612   %arrayidx5 = getelementptr inbounds float, ptr addrspace(1) %out, i64 %idxprom
2613   store float %call3, ptr addrspace(1) %arrayidx5, align 4
2614   ret void
2617 define internal float @pow_wrapper(float %arg, float %arg1) {
2618 ; TUNIT: Function Attrs: norecurse
2619 ; TUNIT-LABEL: define internal float @pow_wrapper
2620 ; TUNIT-SAME: (float noundef nofpclass(nan inf) [[ARG:%.*]], float noundef nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR16:[0-9]+]] {
2621 ; TUNIT-NEXT:  bb:
2622 ; TUNIT-NEXT:    [[I:%.*]] = tail call float @pow_impl(float noundef nofpclass(nan inf) [[ARG]], float noundef nofpclass(nan inf) [[ARG1]])
2623 ; TUNIT-NEXT:    ret float [[I]]
2625 ; CGSCC-LABEL: define internal float @pow_wrapper
2626 ; CGSCC-SAME: (float noundef nofpclass(nan inf) [[ARG:%.*]], float noundef nofpclass(nan inf) [[ARG1:%.*]]) {
2627 ; CGSCC-NEXT:  bb:
2628 ; CGSCC-NEXT:    [[I:%.*]] = tail call float @pow_impl(float noundef nofpclass(nan inf) [[ARG]], float noundef nofpclass(nan inf) [[ARG1]])
2629 ; CGSCC-NEXT:    ret float [[I]]
2632   %i = tail call float @pow_impl(float %arg, float %arg1)
2633   ret float %i
2636 ; nofpclass(nan inf) should reach here through pow_wrapper
2637 define internal float @pow_impl(float %arg, float %arg1) {
2638 ; TUNIT: Function Attrs: norecurse
2639 ; TUNIT-LABEL: define internal float @pow_impl
2640 ; TUNIT-SAME: (float noundef nofpclass(nan inf) [[ARG:%.*]], float noundef nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR16]] {
2641 ; TUNIT-NEXT:  bb:
2642 ; TUNIT-NEXT:    [[IMPLEMENT_POW:%.*]] = call float asm "
2643 ; TUNIT-NEXT:    ret float [[IMPLEMENT_POW]]
2645 ; CGSCC: Function Attrs: norecurse
2646 ; CGSCC-LABEL: define internal float @pow_impl
2647 ; CGSCC-SAME: (float [[ARG:%.*]], float [[ARG1:%.*]]) #[[ATTR16:[0-9]+]] {
2648 ; CGSCC-NEXT:  bb:
2649 ; CGSCC-NEXT:    [[IMPLEMENT_POW:%.*]] = call float asm "
2650 ; CGSCC-NEXT:    ret float [[IMPLEMENT_POW]]
2653   %implement.pow = call float asm " ; do pow $0, $1, $2", "=v,v,v"(float %arg, float %arg1)
2654   ret float %implement.pow
2657 define [4 x float] @constant_aggregate_zero() {
2658 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2659 ; CHECK-LABEL: define nofpclass(nan inf nzero sub norm) [4 x float] @constant_aggregate_zero
2660 ; CHECK-SAME: () #[[ATTR3]] {
2661 ; CHECK-NEXT:    ret [4 x float] zeroinitializer
2663   ret [4 x float] zeroinitializer
2666 define <vscale x 4 x float> @scalable_splat_pnorm() {
2667 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2668 ; CHECK-LABEL: define <vscale x 4 x float> @scalable_splat_pnorm
2669 ; CHECK-SAME: () #[[ATTR3]] {
2670 ; CHECK-NEXT:    ret <vscale x 4 x float> splat (float 1.000000e+00)
2672   ret <vscale x 4 x float> splat (float 1.0)
2675 define <vscale x 4 x float> @scalable_splat_zero() {
2676 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2677 ; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub norm) <vscale x 4 x float> @scalable_splat_zero
2678 ; CHECK-SAME: () #[[ATTR3]] {
2679 ; CHECK-NEXT:    ret <vscale x 4 x float> zeroinitializer
2681   ret <vscale x 4 x float> zeroinitializer
2684 ; Verify we do not derive 'nofpclass(inf zero sub norm)' for the argument __x.
2685 ; See https://github.com/llvm/llvm-project/issues/78507
2687 define double @call_abs(double noundef %__x) {
2688 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2689 ; TUNIT-LABEL: define noundef nofpclass(ninf nzero nsub nnorm) double @call_abs
2690 ; TUNIT-SAME: (double noundef [[__X:%.*]]) #[[ATTR3]] {
2691 ; TUNIT-NEXT:  entry:
2692 ; TUNIT-NEXT:    [[ABS:%.*]] = tail call noundef nofpclass(ninf nzero nsub nnorm) double @llvm.fabs.f64(double noundef [[__X]]) #[[ATTR22]]
2693 ; TUNIT-NEXT:    ret double [[ABS]]
2695 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2696 ; CGSCC-LABEL: define noundef nofpclass(ninf nzero nsub nnorm) double @call_abs
2697 ; CGSCC-SAME: (double noundef [[__X:%.*]]) #[[ATTR3]] {
2698 ; CGSCC-NEXT:  entry:
2699 ; CGSCC-NEXT:    [[ABS:%.*]] = tail call noundef nofpclass(ninf nzero nsub nnorm) double @llvm.fabs.f64(double noundef [[__X]]) #[[ATTR19]]
2700 ; CGSCC-NEXT:    ret double [[ABS]]
2702 entry:
2703   %abs = tail call double @llvm.fabs.f64(double %__x)
2704   ret double %abs
2707 define float @bitcast_to_float_sign_0(i32 %arg) {
2708 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2709 ; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @bitcast_to_float_sign_0
2710 ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] {
2711 ; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[ARG]], 1
2712 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[SHR]] to float
2713 ; CHECK-NEXT:    ret float [[CAST]]
2715   %shr = lshr i32 %arg, 1
2716   %cast = bitcast i32 %shr to float
2717   ret float %cast
2720 define float @bitcast_to_float_nnan(i32 %arg) {
2721 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2722 ; CHECK-LABEL: define nofpclass(nan inf nzero nsub nnorm) float @bitcast_to_float_nnan
2723 ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] {
2724 ; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[ARG]], 2
2725 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[SHR]] to float
2726 ; CHECK-NEXT:    ret float [[CAST]]
2728   %shr = lshr i32 %arg, 2
2729   %cast = bitcast i32 %shr to float
2730   ret float %cast
2733 define float @bitcast_to_float_sign_1(i32 %arg) {
2734 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2735 ; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @bitcast_to_float_sign_1
2736 ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] {
2737 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[ARG]], -2147483648
2738 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[OR]] to float
2739 ; CHECK-NEXT:    ret float [[CAST]]
2741   %or = or i32 %arg, -2147483648
2742   %cast = bitcast i32 %or to float
2743   ret float %cast
2746 define float @bitcast_to_float_nan(i32 %arg) {
2747 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2748 ; CHECK-LABEL: define nofpclass(inf zero sub norm) float @bitcast_to_float_nan
2749 ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] {
2750 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[ARG]], 2139095041
2751 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[OR]] to float
2752 ; CHECK-NEXT:    ret float [[CAST]]
2754   %or = or i32 %arg, 2139095041
2755   %cast = bitcast i32 %or to float
2756   ret float %cast
2759 define float @bitcast_to_float_zero(i32 %arg) {
2760 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2761 ; CHECK-LABEL: define nofpclass(nan inf sub norm) float @bitcast_to_float_zero
2762 ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] {
2763 ; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[ARG]], 31
2764 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[SHL]] to float
2765 ; CHECK-NEXT:    ret float [[CAST]]
2767   %shl = shl i32 %arg, 31
2768   %cast = bitcast i32 %shl to float
2769   ret float %cast
2772 define float @bitcast_to_float_nzero(i32 %arg) {
2773 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2774 ; CHECK-LABEL: define nofpclass(zero) float @bitcast_to_float_nzero
2775 ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] {
2776 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[ARG]], 134217728
2777 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[OR]] to float
2778 ; CHECK-NEXT:    ret float [[CAST]]
2780   %or = or i32 %arg, 134217728
2781   %cast = bitcast i32 %or to float
2782   ret float %cast
2785 define float @bitcast_to_float_inf(i32 %arg) {
2786 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2787 ; CHECK-LABEL: define nofpclass(nan zero sub norm) float @bitcast_to_float_inf
2788 ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] {
2789 ; CHECK-NEXT:    [[SHR:%.*]] = shl i32 [[ARG]], 31
2790 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[SHR]], 2139095040
2791 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast i32 [[OR]] to float
2792 ; CHECK-NEXT:    ret float [[CAST]]
2794   %shr = shl i32 %arg, 31
2795   %or = or i32 %shr, 2139095040
2796   %cast = bitcast i32 %or to float
2797   ret float %cast
2800 define double @bitcast_to_double_sign_0(i64 %arg) {
2801 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2802 ; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) double @bitcast_to_double_sign_0
2803 ; CHECK-SAME: (i64 [[ARG:%.*]]) #[[ATTR3]] {
2804 ; CHECK-NEXT:    [[SHR:%.*]] = lshr i64 [[ARG]], 1
2805 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast i64 [[SHR]] to double
2806 ; CHECK-NEXT:    ret double [[CAST]]
2808   %shr = lshr i64 %arg, 1
2809   %cast = bitcast i64 %shr to double
2810   ret double %cast
2813 define double @bitcast_to_double_nnan(i64 %arg) {
2814 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2815 ; CHECK-LABEL: define nofpclass(nan inf nzero nsub nnorm) double @bitcast_to_double_nnan
2816 ; CHECK-SAME: (i64 [[ARG:%.*]]) #[[ATTR3]] {
2817 ; CHECK-NEXT:    [[SHR:%.*]] = lshr i64 [[ARG]], 2
2818 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast i64 [[SHR]] to double
2819 ; CHECK-NEXT:    ret double [[CAST]]
2821   %shr = lshr i64 %arg, 2
2822   %cast = bitcast i64 %shr to double
2823   ret double %cast
2826 define double @bitcast_to_double_sign_1(i64 %arg) {
2827 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2828 ; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) double @bitcast_to_double_sign_1
2829 ; CHECK-SAME: (i64 [[ARG:%.*]]) #[[ATTR3]] {
2830 ; CHECK-NEXT:    [[OR:%.*]] = or i64 [[ARG]], -9223372036854775808
2831 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast i64 [[OR]] to double
2832 ; CHECK-NEXT:    ret double [[CAST]]
2834   %or = or i64 %arg, -9223372036854775808
2835   %cast = bitcast i64 %or to double
2836   ret double %cast
2839 define double @bitcast_to_double_nan(i64 %arg) {
2840 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2841 ; CHECK-LABEL: define nofpclass(inf zero sub norm) double @bitcast_to_double_nan
2842 ; CHECK-SAME: (i64 [[ARG:%.*]]) #[[ATTR3]] {
2843 ; CHECK-NEXT:    [[OR:%.*]] = or i64 [[ARG]], -4503599627370495
2844 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast i64 [[OR]] to double
2845 ; CHECK-NEXT:    ret double [[CAST]]
2847   %or = or i64 %arg, -4503599627370495
2848   %cast = bitcast i64 %or to double
2849   ret double %cast
2853 define double @bitcast_to_double_zero(i64 %arg) {
2854 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2855 ; CHECK-LABEL: define nofpclass(nan inf sub norm) double @bitcast_to_double_zero
2856 ; CHECK-SAME: (i64 [[ARG:%.*]]) #[[ATTR3]] {
2857 ; CHECK-NEXT:    [[SHL:%.*]] = shl i64 [[ARG]], 63
2858 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast i64 [[SHL]] to double
2859 ; CHECK-NEXT:    ret double [[CAST]]
2861   %shl = shl i64 %arg, 63
2862   %cast = bitcast i64 %shl to double
2863   ret double %cast
2866 define double @bitcast_to_double_nzero(i64 %arg) {
2867 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2868 ; CHECK-LABEL: define nofpclass(zero) double @bitcast_to_double_nzero
2869 ; CHECK-SAME: (i64 [[ARG:%.*]]) #[[ATTR3]] {
2870 ; CHECK-NEXT:    [[OR:%.*]] = or i64 [[ARG]], 1152921504606846976
2871 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast i64 [[OR]] to double
2872 ; CHECK-NEXT:    ret double [[CAST]]
2874   %or = or i64 %arg, 1152921504606846976
2875   %cast = bitcast i64 %or to double
2876   ret double %cast
2879 define double @bitcast_to_double_inf(i64 %arg) {
2880 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2881 ; CHECK-LABEL: define nofpclass(nan zero sub norm) double @bitcast_to_double_inf
2882 ; CHECK-SAME: (i64 [[ARG:%.*]]) #[[ATTR3]] {
2883 ; CHECK-NEXT:    [[SHR:%.*]] = shl i64 [[ARG]], 63
2884 ; CHECK-NEXT:    [[OR:%.*]] = or i64 [[SHR]], 9218868437227405312
2885 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast i64 [[OR]] to double
2886 ; CHECK-NEXT:    ret double [[CAST]]
2888   %shr = shl i64 %arg, 63
2889   %or = or i64 %shr, 9218868437227405312
2890   %cast = bitcast i64 %or to double
2891   ret double %cast
2895 define <2 x float> @bitcast_to_float_vect_sign_0(<2 x i32> %arg) {
2896 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2897 ; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) <2 x float> @bitcast_to_float_vect_sign_0
2898 ; CHECK-SAME: (<2 x i32> [[ARG:%.*]]) #[[ATTR3]] {
2899 ; CHECK-NEXT:    [[SHR:%.*]] = lshr <2 x i32> [[ARG]], <i32 1, i32 2>
2900 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast <2 x i32> [[SHR]] to <2 x float>
2901 ; CHECK-NEXT:    ret <2 x float> [[CAST]]
2903   %shr = lshr <2 x i32> %arg, <i32 1, i32 2>
2904   %cast = bitcast <2 x i32> %shr to <2 x float>
2905   ret <2 x float> %cast
2908 define <2 x float> @bitcast_to_float_vect_nnan(<2 x i32> %arg) {
2909 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2910 ; CHECK-LABEL: define nofpclass(nan inf nzero nsub nnorm) <2 x float> @bitcast_to_float_vect_nnan
2911 ; CHECK-SAME: (<2 x i32> [[ARG:%.*]]) #[[ATTR3]] {
2912 ; CHECK-NEXT:    [[SHR:%.*]] = lshr <2 x i32> [[ARG]], splat (i32 4)
2913 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast <2 x i32> [[SHR]] to <2 x float>
2914 ; CHECK-NEXT:    ret <2 x float> [[CAST]]
2916   %shr = lshr <2 x i32> %arg, <i32 4, i32 4>
2917   %cast = bitcast <2 x i32> %shr to <2 x float>
2918   ret <2 x float> %cast
2921 define <2 x float> @bitcast_to_float_vect_sign_1(<2 x i32> %arg) {
2922 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2923 ; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) <2 x float> @bitcast_to_float_vect_sign_1
2924 ; CHECK-SAME: (<2 x i32> [[ARG:%.*]]) #[[ATTR3]] {
2925 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[ARG]], splat (i32 -2147483648)
2926 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast <2 x i32> [[OR]] to <2 x float>
2927 ; CHECK-NEXT:    ret <2 x float> [[CAST]]
2929   %or = or <2 x i32> %arg, <i32 -2147483648, i32 -2147483648>
2930   %cast = bitcast <2 x i32> %or to <2 x float>
2931   ret <2 x float> %cast
2934 define <2 x float> @bitcast_to_float_vect_nan(<2 x i32> %arg) {
2935 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2936 ; CHECK-LABEL: define nofpclass(inf zero sub norm) <2 x float> @bitcast_to_float_vect_nan
2937 ; CHECK-SAME: (<2 x i32> [[ARG:%.*]]) #[[ATTR3]] {
2938 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[ARG]], splat (i32 2139095041)
2939 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast <2 x i32> [[OR]] to <2 x float>
2940 ; CHECK-NEXT:    ret <2 x float> [[CAST]]
2942   %or = or <2 x i32> %arg, <i32 2139095041, i32 2139095041>
2943   %cast = bitcast <2 x i32> %or to <2 x float>
2944   ret <2 x float> %cast
2947 define <2 x float> @bitcast_to_float_vect_conservative_1(<2 x i32> %arg) {
2948 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2949 ; CHECK-LABEL: define <2 x float> @bitcast_to_float_vect_conservative_1
2950 ; CHECK-SAME: (<2 x i32> [[ARG:%.*]]) #[[ATTR3]] {
2951 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[ARG]], <i32 -2147483648, i32 0>
2952 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast <2 x i32> [[OR]] to <2 x float>
2953 ; CHECK-NEXT:    ret <2 x float> [[CAST]]
2955   %or = or <2 x i32> %arg, <i32 -2147483648, i32 0>
2956   %cast = bitcast <2 x i32> %or to <2 x float>
2957   ret <2 x float> %cast
2960 define <2 x float> @bitcast_to_float_vect_conservative_2(<2 x i32> %arg) {
2961 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2962 ; CHECK-LABEL: define <2 x float> @bitcast_to_float_vect_conservative_2
2963 ; CHECK-SAME: (<2 x i32> [[ARG:%.*]]) #[[ATTR3]] {
2964 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[ARG]], <i32 0, i32 2139095041>
2965 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast <2 x i32> [[OR]] to <2 x float>
2966 ; CHECK-NEXT:    ret <2 x float> [[CAST]]
2968   %or = or <2 x i32> %arg, <i32 0, i32 2139095041>
2969   %cast = bitcast <2 x i32> %or to <2 x float>
2970   ret <2 x float> %cast
2973 declare i64 @_Z13get_global_idj(i32 noundef)
2975 attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }
2976 attributes #1 = { "denormal-fp-math"="preserve-sign,ieee" }
2977 attributes #2 = { "denormal-fp-math"="ieee,preserve-sign" }
2978 attributes #3 = { "denormal-fp-math"="positive-zero,positive-zero" }
2979 attributes #4 = { "denormal-fp-math"="positive-zero,ieee" }
2980 attributes #5 = { "denormal-fp-math"="ieee,positive-zero" }