xref: /llvm-project/llvm/test/Transforms/Attributor/nofpclass.ll (revision 29441e4f5fa5f5c7709f7cf180815ba97f611297)
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
4
5declare nofpclass(nan) float @ret_nofpclass_nan()
6declare [2 x [3 x float]] @ret_array()
7declare float @extern()
8declare float @extern.f32(float)
9declare void @extern.use(float)
10declare void @extern.use.array([2 x [3 x float]])
11declare void @llvm.assume(i1 noundef)
12declare void @unknown()
13declare half @llvm.fabs.f16(half)
14declare float @llvm.fabs.f32(float)
15declare void @extern.use.f16(half)
16declare i1 @llvm.is.fpclass.f32(float, i32 immarg)
17declare float @llvm.experimental.constrained.sitofp.f32.i32(i32, metadata, metadata)
18declare float @llvm.experimental.constrained.uitofp.f32.i32(i32, metadata, metadata)
19declare float @llvm.arithmetic.fence.f32(float)
20
21define 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
25;
26  call void @unknown()
27  ret float 0.0
28}
29
30define 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
34;
35  call void @unknown()
36  ret float -0.0
37}
38
39define float @returned_undef() {
40; CHECK-LABEL: define nofpclass(all) float @returned_undef() {
41; CHECK-NEXT:    call void @unknown()
42; CHECK-NEXT:    ret float undef
43;
44  call void @unknown()
45  ret float undef
46}
47
48define float @returned_poison() {
49; CHECK-LABEL: define nofpclass(all) float @returned_poison() {
50; CHECK-NEXT:    call void @unknown()
51; CHECK-NEXT:    ret float poison
52;
53  call void @unknown()
54  ret float poison
55}
56
57; Know nothing
58define 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]]
63;
64  call void @unknown()
65  %freeze.poison = freeze float poison
66  ret float %freeze.poison
67}
68
69define 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
73;
74  call void @unknown()
75  ret double 0x7FF0000000000001
76}
77
78define 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
82;
83  call void @unknown()
84  ret double 0x7FF8000000000000
85}
86
87define <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
91;
92  call void @unknown()
93  ret <2 x double> zeroinitializer
94}
95
96define <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)
100;
101  call void @unknown()
102  ret <2 x double> <double -0.0, double -0.0>
103}
104
105; Test a vector element that's a constant but not ConstantFP.
106define <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)>
110;
111  call void @unknown()
112  ret <2 x double> <double -0.0, double bitcast (i64 ptrtoint (ptr @unknown to i64) to double)>
113}
114
115; Test a vector element that's undef
116define <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>
120;
121  call void @unknown()
122  ret <3 x double> <double -0.0, double 0.0, double undef>
123}
124
125; Test a vector element that's poison
126define <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>
130;
131  call void @unknown()
132  ret <3 x double> <double -0.0, double 0.0, double poison>
133}
134
135define <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>
139;
140  call void @unknown()
141  ret <2 x double> <double 0x7FF8000000000000, double 0.0>
142}
143
144; Return a float trivially nofpclass(nan) (call return attribute)
145define 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]]
149;
150  %ret = call float @ret_nofpclass_nan()
151  ret float %ret
152}
153
154; Return a float trivially nofpclass(nan) (argument attribute)
155define 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]]
160;
161  ret float %p
162}
163
164define [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]]
168;
169  %ret = call nofpclass(inf) [2 x [3 x float]]  @ret_array()
170  ret [2 x [3 x float]] %ret
171}
172
173define 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]]
179;
180  %fadd = fadd nnan float %arg0, %arg1
181  ret float %fadd
182}
183
184define 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]]
188;
189  %call = call nofpclass(nan) float @extern()
190  ret float %call
191}
192
193; Can union the return classes
194define 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]]
198;
199  %call = call nofpclass(nan) float @extern()
200  ret float %call
201}
202
203define 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
208;
209  call void @extern.use(float nofpclass(nan) %arg)
210  ret void
211}
212
213; Callsite can union the incoming and outgoing
214define 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
219;
220  call void @extern.use(float nofpclass(nan) %arg)
221  ret void
222}
223
224define 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
229;
230  call void @extern.use.array([2 x [3 x float]]  %arg)
231  ret void
232}
233
234define 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
240;
241  call void @extern(float %arg) willreturn nounwind ; < annotate this use
242  call void @extern(float nofpclass(nan inf) %arg)
243  ret void
244}
245
246define 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
251;
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
256;
257  %call = call float @mutually_recursive1(float %arg)
258  ret float %call
259}
260
261define 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
266;
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
271;
272  %call = call float @mutually_recursive0(float %arg)
273  ret float %call
274}
275
276define 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]]
288;
289entry:
290  %ret = call float @ret_nofpclass_nan()
291  br label %loop
292
293loop:
294  %phi = phi float [%ret, %entry], [%phi, %loop]
295  %cond = load volatile i1, ptr %ptr
296  br i1 %cond, label %loop, label %exit
297
298exit:
299  ret float %phi
300}
301
302; Should be able to infer nofpclass(nan) return
303define 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]]
315;
316entry:
317  %isnan = fcmp uno float %arg, 0.0
318  br i1 %isnan, label %bb0, label %bb1
319
320bb0:
321  %call = call float @ret_nofpclass_nan()
322  br label %bb1
323
324bb1:
325  %phi = phi float [ %call, %bb0 ], [ %arg, %entry ]
326  ret float %phi
327}
328
329; Should be able to infer nofpclass(nan) on %arg use
330define 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
341;
342entry:
343  %is.not.nan = fcmp ord float %arg, 0.0
344  br i1 %is.not.nan, label %bb0, label %bb1
345
346bb0:
347  call void @extern.use(float %arg)
348  br label %bb1
349
350bb1:
351  ret void
352}
353
354; Should be able to infer nofpclass on both %arg uses
355define 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]]
363;
364entry:
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
369}
370
371define 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
375;
376  call void @unknown()
377  ret float 0.0
378}
379
380define 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
384;
385  call float @returned_dead()
386  ret void
387}
388
389define 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]]
395;
396  %add = fadd float %arg, %arg
397  ret float %add
398}
399
400define 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]]
406;
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]]
412;
413  %result = call float @only_nofpclass_inf_callers(float %arg)
414  ret float %result
415}
416
417define 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]]
423;
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]]
429;
430  %result = call float @only_nofpclass_inf_callers(float nofpclass(inf) %arg)
431  ret float %result
432}
433
434; TODO: Should be able to infer nofpclass(inf) on return
435define 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]]
441;
442  %add = fadd float %arg, %arg
443  ret float %add
444}
445
446define 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]]
452;
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]]
458;
459  %result = call nofpclass(inf) float @only_nofpclass_inf_return_users(float %arg)
460  ret float %result
461}
462
463define 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]]
469;
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]]
475;
476  %result = call nofpclass(inf) float @only_nofpclass_inf_return_users(float %arg)
477  ret float %result
478}
479
480define 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]]
488;
489entry:
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
494}
495
496define 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]]
504;
505entry:
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
510}
511
512define 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]]
521;
522entry:
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
528}
529
530; Assume is after the call, shouldn't mark callsite.
531define 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]]
539;
540entry:
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
545}
546
547; Assume not subnormal or zero, and not infinity
548define 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]]
559;
560entry:
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)
564
565  %not.inf = fcmp one half %arg, 0xH7C00
566  call void @llvm.assume(i1 %not.inf)
567
568  call void @extern.use.f16(half %arg)
569  ret half %arg
570}
571
572define 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]]
580;
581entry:
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
586}
587
588; Make sure we don't get confused by looking at an unrelated assume
589; based on the fabs of the value.
590define 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]]
602;
603entry:
604
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
613}
614
615; Make sure if looking through the fabs finds a different source
616; value, we still identify a test mask by ignoring the fabs
617define 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]]
629;
630entry:
631
632  %fabs = call half @llvm.fabs.f16(half %arg)
633
634  %one.inf = fcmp one half %arg, 0xH7C00
635  call void @llvm.assume(i1 %one.inf)
636
637  %unrelated.fabs = fcmp oeq half %fabs, 0.0
638  call void @llvm.assume(i1 %unrelated.fabs)
639
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
645}
646
647define 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]]
660;
661entry:
662  br i1 %c, label %A, label %B
663
664A:
665  call void @llvm.assume(i1 true) [ "nofpclass"(float %ret, i32 3) ]
666  call void @extern.use(float %ret)
667  ret float %ret
668
669B:
670  call void @llvm.assume(i1 true) [ "nofpclass"(float %ret, i32 12) ]
671  call void @extern.use(float %ret)
672  ret float %ret
673}
674
675define 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 nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[PTR:%.*]]) #[[ATTR5:[0-9]+]] {
679; CHECK-NEXT:    [[LOAD:%.*]] = load float, ptr [[PTR]], align 4
680; CHECK-NEXT:    ret float [[LOAD]]
681;
682  %load = load float, ptr %ptr
683  ret float %load
684}
685
686define 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 nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[ALLOCA]]) #[[ATTR21:[0-9]+]]
693; TUNIT-NEXT:    ret float [[RET]]
694;
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 nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[ALLOCA]]) #[[ATTR21:[0-9]+]]
701; CGSCC-NEXT:    ret float [[RET]]
702;
703  %alloca = alloca float
704  store float %arg, ptr %alloca
705  %ret = call float @returned_load(ptr %alloca)
706  ret float %ret
707}
708
709define 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]]
715;
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]]
721;
722  %fabs = call float @llvm.fabs.f32(float %x)
723  ret float %fabs
724}
725
726define 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]]
732;
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]]
738;
739  %fabs = call float @llvm.fabs.f32(float %x)
740  ret float %fabs
741}
742
743define 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]]
749;
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]]
755;
756  %fabs = call float @llvm.fabs.f32(float %x)
757  ret float %fabs
758}
759
760define 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]]
766;
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]]
772;
773  %fabs = call float @llvm.fabs.f32(float %x)
774  ret float %fabs
775}
776
777define 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]]
783;
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]]
789;
790  %fabs = call float @llvm.fabs.f32(float %x)
791  ret float %fabs
792}
793
794define 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]]
800;
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]]
806;
807  %fabs = call float @llvm.fabs.f32(float %x)
808  ret float %fabs
809}
810
811define 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]]
817;
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]]
823;
824  %fabs = call float @llvm.fabs.f32(float %x)
825  ret float %fabs
826}
827
828define 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]]
834;
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]]
840;
841  %fabs = call float @llvm.fabs.f32(float %x)
842  ret float %fabs
843}
844
845define 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]]
851;
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]]
857;
858  %fabs = call float @llvm.fabs.f32(float %x)
859  ret float %fabs
860}
861
862define 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]]
868;
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]]
874;
875  %fabs = call float @llvm.fabs.f32(float %x)
876  ret float %fabs
877}
878
879define 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]]
885;
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]]
891;
892  %fabs = call float @llvm.fabs.f32(float %x)
893  ret float %fabs
894}
895
896define 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]]
902;
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]]
908;
909  %fabs = call float @llvm.fabs.f32(float %x)
910  ret float %fabs
911}
912
913define 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]]
919;
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]]
925;
926  %fabs = call float @llvm.fabs.f32(float %x)
927  ret float %fabs
928}
929
930define 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]]
936;
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]]
942;
943  %fabs = call float @llvm.fabs.f32(float %x)
944  ret float %fabs
945}
946
947define 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]]
953;
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]]
959;
960  %fabs = call float @llvm.fabs.f32(float %x)
961  ret float %fabs
962}
963
964define 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]]
970;
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]]
976;
977  %fabs = call float @llvm.fabs.f32(float %x)
978  ret float %fabs
979}
980
981define 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]]
987;
988  %fneg = fneg float %x
989  ret float %fneg
990}
991
992define 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]]
998;
999  %fneg = fneg float %x
1000  ret float %fneg
1001}
1002
1003define 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]]
1009;
1010  %fneg = fneg float %x
1011  ret float %fneg
1012}
1013
1014define 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]]
1020;
1021  %fneg = fneg ninf float %x
1022  ret float %fneg
1023}
1024
1025define 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]]
1031;
1032  %fneg = fneg float %x
1033  ret float %fneg
1034}
1035
1036define 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]]
1042;
1043  %fneg = fneg float %x
1044  ret float %fneg
1045}
1046
1047define 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]]
1053;
1054  %fneg = fneg float %x
1055  ret float %fneg
1056}
1057
1058define 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]]
1064;
1065  %fneg = fneg nnan float %x
1066  ret float %fneg
1067}
1068
1069define 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]]
1075;
1076  %fneg = fneg float %x
1077  ret float %fneg
1078}
1079
1080define 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]]
1086;
1087  %fneg = fneg float %x
1088  ret float %fneg
1089}
1090
1091define 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]]
1097;
1098  %fneg = fneg float %x
1099  ret float %fneg
1100}
1101
1102define 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]]
1108;
1109  %fneg = fneg float %x
1110  ret float %fneg
1111}
1112
1113define 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]]
1120;
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]]
1127;
1128  %fabs = call float @llvm.fabs.f32(float %x)
1129  %fneg.fabs = fneg float %fabs
1130  ret float %fneg.fabs
1131}
1132
1133define 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]]
1140;
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]]
1147;
1148  %fabs = call float @llvm.fabs.f32(float %x)
1149  %fneg.fabs = fneg float %fabs
1150  ret float %fneg.fabs
1151}
1152
1153define 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]]
1160;
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]]
1167;
1168  %fabs = call float @llvm.fabs.f32(float %x)
1169  %fneg.fabs = fneg float %fabs
1170  ret float %fneg.fabs
1171}
1172
1173define 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]]
1180;
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]]
1187;
1188  %fabs = call float @llvm.fabs.f32(float %x)
1189  %fneg.fabs = fneg float %fabs
1190  ret float %fneg.fabs
1191}
1192
1193define 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]]
1200;
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]]
1207;
1208  %fabs = call float @llvm.fabs.f32(float %x)
1209  %fneg.fabs = fneg float %fabs
1210  ret float %fneg.fabs
1211}
1212
1213define 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]]
1220;
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]]
1227;
1228  %fabs = call float @llvm.fabs.f32(float %x)
1229  %fneg.fabs = fneg float %fabs
1230  ret float %fneg.fabs
1231}
1232
1233define 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]]
1240;
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]]
1247;
1248  %fabs = call float @llvm.fabs.f32(float %x)
1249  %fneg.fabs = fneg float %fabs
1250  ret float %fneg.fabs
1251}
1252
1253define 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]]
1260;
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]]
1267;
1268  %fabs = call ninf float @llvm.fabs.f32(float %x)
1269  %fneg.fabs = fneg float %fabs
1270  ret float %fneg.fabs
1271}
1272
1273define 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]]
1280;
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]]
1287;
1288  %fabs = call float @llvm.fabs.f32(float %x)
1289  %fneg.fabs = fneg ninf float %fabs
1290  ret float %fneg.fabs
1291}
1292
1293define 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]]
1299;
1300  %cvt = uitofp i32 %arg to float
1301  ret float %cvt
1302}
1303
1304define 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]]
1310;
1311  %cvt = sitofp i32 %arg to float
1312  ret float %cvt
1313}
1314
1315define <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]]
1321;
1322  %cvt = uitofp <2 x i32> %arg to <2 x float>
1323  ret <2 x float> %cvt
1324}
1325
1326define <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]]
1332;
1333  %cvt = sitofp <2 x i32> %arg to <2 x float>
1334  ret <2 x float> %cvt
1335}
1336
1337define 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]]
1343;
1344  %cvt = uitofp i17 %arg to half
1345  ret half %cvt
1346}
1347
1348define 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]]
1354;
1355  %cvt = sitofp i17 %arg to half
1356  ret half %cvt
1357}
1358
1359define <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]]
1365;
1366  %cvt = uitofp <2 x i17> %arg to <2 x half>
1367  ret <2 x half> %cvt
1368}
1369
1370define <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]]
1376;
1377  %cvt = sitofp <2 x i17> %arg to <2 x half>
1378  ret <2 x half> %cvt
1379}
1380
1381define 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]]
1391;
1392entry:
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
1399}
1400
1401define 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]]
1411;
1412entry:
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)
1417
1418  call void @extern.use(float %arg)
1419  ret float %arg
1420}
1421
1422define 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]]
1432;
1433entry:
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
1440}
1441
1442define 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]]
1448;
1449  %extract = extractelement <4 x float> %vec, i32 %idx
1450  ret float %extract
1451}
1452
1453define 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]]
1459;
1460  %extract = extractelement <4 x float> %vec, i32 0
1461  ret float %extract
1462}
1463
1464define 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]]
1470;
1471  %extract = extractelement <4 x float> %vec, i32 5
1472  ret float %extract
1473}
1474
1475define 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]]
1481;
1482  %extract = extractelement <vscale x 4 x float> %vec, i32 0
1483  ret float %extract
1484}
1485
1486define 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]]
1492;
1493  %extract = extractvalue [4 x float] %array, 0
1494  ret float %extract
1495}
1496
1497define 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]]
1503;
1504  %freeze = freeze float %arg
1505  ret float %freeze
1506}
1507
1508define 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]]
1515;
1516  %freeze = freeze <2 x float> %arg
1517  %elt = extractelement <2 x float> %freeze, i32 0
1518  ret float %elt
1519}
1520
1521define <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]]
1530;
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
1536}
1537
1538define <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]]
1548;
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
1555}
1556
1557define <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]]
1566;
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
1572}
1573
1574define <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]]
1580;
1581  %insert = insertelement <4 x float> %arg0, float 0.0, i32 1
1582  ret <4 x float> %insert
1583}
1584
1585define 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]]
1592;
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
1596}
1597
1598define 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]]
1605;
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
1609}
1610
1611define 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]]
1618;
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
1622}
1623
1624define <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]]
1630;
1631  %insert = insertelement <4 x float> zeroinitializer, float 0x7FF0000000000000, i32 4
1632  ret <4 x float> %insert
1633}
1634
1635define <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]]
1645;
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
1652}
1653
1654; FIXME: Doesn't actually reach computeKnownFPClass
1655define <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>
1660;
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>)
1662}
1663
1664define <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]]
1670;
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
1673}
1674
1675define <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]]
1681;
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
1684}
1685
1686define <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]]
1692;
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
1695}
1696
1697define <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]]
1703;
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
1706}
1707
1708define <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]]
1714;
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
1717}
1718
1719define <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]]
1725;
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
1728}
1729
1730define <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]]
1736;
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
1739}
1740
1741define <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]]
1747;
1748  %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> undef
1749  ret <4 x float> %shuffle
1750}
1751
1752define <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]]
1758;
1759  %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> zeroinitializer
1760  ret <4 x float> %shuffle
1761}
1762
1763define 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]]
1770;
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
1774}
1775
1776define 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]]
1783;
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
1787}
1788
1789define 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]]
1796;
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
1800}
1801
1802define 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]]
1809;
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
1813}
1814
1815define 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]]
1822;
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
1826}
1827
1828define 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]]
1835;
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
1839}
1840
1841define 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]]
1848;
1849  %fptosi = fptosi float %arg to i32
1850  %add = add i32 %fptosi, 1
1851  ret i32 %add
1852}
1853
1854define 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]]
1861;
1862  %cast = fptrunc double %arg to float
1863  %mul = fmul float %cast, %cast
1864  ret float %mul
1865}
1866
1867define 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]]
1874;
1875  %cast = fpext float %arg to double
1876  %mul = fmul double %cast, %cast
1877  ret double %mul
1878}
1879
1880define 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 nofree noundef nonnull align 4 captures(none) 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]]
1886;
1887  %result = atomicrmw fadd ptr %ptr, float %val seq_cst
1888  ret float %result
1889}
1890
1891define 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 nofree noundef nonnull align 4 captures(none) 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]]
1899;
1900  store float %val, ptr %ptr
1901  %load = load float, ptr %ptr
1902  %mul = fmul float %load, %load
1903  ret float %mul
1904}
1905
1906define 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 nofree noundef nonnull align 4 captures(none) 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]]
1914;
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
1919}
1920
1921define <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]]
1929;
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
1934}
1935
1936define 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]]
1942;
1943  %val = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %arg, metadata !"round.dynamic", metadata !"fpexcept.strict")
1944  ret float %val
1945}
1946
1947define 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]]
1953;
1954  %val = call float @llvm.experimental.constrained.uitofp.f32.i32(i32 %arg, metadata !"round.dynamic", metadata !"fpexcept.strict")
1955  ret float %val
1956}
1957
1958define 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]]
1964;
1965  %add = fadd float %arg0, 0.0
1966  ret float %add
1967}
1968
1969define 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]]
1975;
1976  %add = fadd float %arg0, -0.0
1977  ret float %add
1978}
1979
1980define 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]]
1986;
1987  %sub = fsub float %arg0, 0.0
1988  ret float %sub
1989}
1990
1991define 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]]
1997;
1998  %sub = fsub float %arg0, -0.0
1999  ret float %sub
2000}
2001
2002define 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]]
2008;
2009  %sub = fsub float 0.0, %arg0
2010  ret float %sub
2011}
2012
2013define 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]]
2019;
2020  %sub = fsub float -0.0, %arg0
2021  ret float %sub
2022}
2023
2024define 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]]
2030;
2031  %add = fadd float %arg0, 0.0
2032  ret float %add
2033}
2034
2035define 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]]
2041;
2042  %add = fadd float %arg0, -0.0
2043  ret float %add
2044}
2045
2046define 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]]
2052;
2053  %sub = fsub float %arg0, 0.0
2054  ret float %sub
2055}
2056
2057define 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]]
2063;
2064  %sub = fsub float %arg0, -0.0
2065  ret float %sub
2066}
2067
2068define 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]]
2074;
2075  %sub = fsub float 0.0, %arg0
2076  ret float %sub
2077}
2078
2079define 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]]
2085;
2086  %sub = fsub float -0.0, %arg0
2087  ret float %sub
2088}
2089
2090define 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]]
2096;
2097  %add = fadd float %arg0, 0.0
2098  ret float %add
2099}
2100
2101define 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]]
2107;
2108  %add = fadd float %arg0, 0.0
2109  ret float %add
2110}
2111
2112define 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]]
2118;
2119  %add = fadd float %arg0, -0.0
2120  ret float %add
2121}
2122
2123define 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]]
2129;
2130  %sub = fsub float %arg0, 0.0
2131  ret float %sub
2132}
2133
2134define 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]]
2140;
2141  %sub = fsub float %arg0, -0.0
2142  ret float %sub
2143}
2144
2145define 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]]
2151;
2152  %sub = fsub float 0.0, %arg0
2153  ret float %sub
2154}
2155
2156define 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]]
2162;
2163  %sub = fsub float -0.0, %arg0
2164  ret float %sub
2165}
2166
2167define 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]]
2173;
2174  %add = fadd float %a, %b
2175  ret float %add
2176}
2177
2178define 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]]
2184;
2185  %add = fadd float %a, %b
2186  ret float %add
2187}
2188
2189define 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]]
2195;
2196  %add = fadd float %a, %b
2197  ret float %add
2198}
2199
2200define 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]]
2206;
2207  %add = fadd float %a, %b
2208  ret float %add
2209}
2210
2211define 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]]
2217;
2218  %add = fadd float %a, %b
2219  ret float %add
2220}
2221
2222define 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]]
2228;
2229  %add = fadd float %a, %b
2230  ret float %add
2231}
2232
2233define 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]]
2239;
2240  %add = fadd float %a, %b
2241  ret float %add
2242}
2243
2244define 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]]
2250;
2251  %add = fadd float %a, %b
2252  ret float %add
2253}
2254
2255define 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]]
2261;
2262  %add = fadd float %arg0, %arg1
2263  ret float %add
2264}
2265
2266define 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]]
2272;
2273  %add = fadd float %arg0, %arg1
2274  ret float %add
2275}
2276
2277define 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]]
2283;
2284  %add = fadd float %arg0, %arg1
2285  ret float %add
2286}
2287
2288define 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]]
2294;
2295  %add = fadd float %arg0, %arg1
2296  ret float %add
2297}
2298
2299define 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]]
2305;
2306  %add = fadd float %arg0, %arg1
2307  ret float %add
2308}
2309
2310define 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]]
2316;
2317  %add = fadd float %arg0, %arg1
2318  ret float %add
2319}
2320
2321define 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]]
2327;
2328  %add = fadd float %arg0, %arg1
2329  ret float %add
2330}
2331
2332define 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]]
2338;
2339  %add = fadd float %arg0, %arg1
2340  ret float %add
2341}
2342
2343define 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]]
2349;
2350  %add = fadd float %arg0, %arg1
2351  ret float %add
2352}
2353
2354define 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]]
2360;
2361  %add = fadd float %arg0, %arg1
2362  ret float %add
2363}
2364
2365define 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]]
2371;
2372  %add = fadd float %arg0, %arg1
2373  ret float %add
2374}
2375
2376define 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]]
2382;
2383  %add = fadd float %arg0, %arg1
2384  ret float %add
2385}
2386
2387define 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]]
2393;
2394  %add = fadd float %arg0, %arg1
2395  ret float %add
2396}
2397
2398define 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]]
2404;
2405  %add = fadd float %arg0, %arg1
2406  ret float %add
2407}
2408
2409define 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]]
2415;
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]]
2421;
2422  %ret = call float @llvm.arithmetic.fence.f32(float %arg)
2423  ret float %ret
2424}
2425
2426; Check that the func0 callsite is marked with both no inf and no nan
2427define 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]]
2434;
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]]
2441;
2442  %func0 = call float @returns_fence(float nofpclass(nan) %arg)
2443  %ret = call float @llvm.arithmetic.fence.f32(float %func0)
2444  ret float %ret
2445}
2446
2447define 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]]
2453;
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]]
2459;
2460  %func1 = call float @refine_callsite_attribute(float %arg)
2461  ret float %func1
2462}
2463
2464; value is passed through memory
2465define 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]]
2473;
2474  %load = load float, ptr %ptr.arg
2475  ret float %load
2476}
2477
2478; value is passed through memory and goes through an inferrable FP user
2479define 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]]
2488;
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]]
2497;
2498  %load = load float, ptr %ptr.arg
2499  %call = call float @llvm.arithmetic.fence.f32(float %load)
2500  ret float %call
2501}
2502
2503; value is passed through memory and goes through an uninferrable FP user
2504define 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]]
2513;
2514  %load = load float, ptr %ptr.arg
2515  %call = call float @extern.f32(float %load)
2516  ret float %call
2517}
2518
2519define 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]]
2526;
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]]
2534;
2535  %alloca = alloca float
2536  store float %val, ptr %alloca
2537  %through_memory = call float @through_memory0(ptr %alloca)
2538  ret float %through_memory
2539}
2540
2541define 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]]
2550;
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]]
2558;
2559  %alloca = alloca float
2560  store float %val, ptr %alloca
2561  %through_memory = call float @through_memory1(ptr %alloca)
2562  ret float %through_memory
2563}
2564
2565define 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]]
2573;
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]]
2580;
2581  %alloca = alloca float
2582  store float %val, ptr %alloca
2583  %through_memory = call float @through_memory2(ptr %alloca)
2584  ret float %through_memory
2585}
2586
2587define 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) nofree noundef writeonly align 4 captures(none) [[OUT:%.*]], ptr addrspace(1) nofree noundef readonly align 4 captures(none) [[IN1:%.*]], ptr addrspace(1) nofree noundef readonly align 4 captures(none) [[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
2602;
2603entry:
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
2615}
2616
2617define 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]]
2624;
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]]
2630;
2631bb:
2632  %i = tail call float @pow_impl(float %arg, float %arg1)
2633  ret float %i
2634}
2635
2636; nofpclass(nan inf) should reach here through pow_wrapper
2637define 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]]
2644;
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]]
2651;
2652bb:
2653  %implement.pow = call float asm " ; do pow $0, $1, $2", "=v,v,v"(float %arg, float %arg1)
2654  ret float %implement.pow
2655}
2656
2657define [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
2662;
2663  ret [4 x float] zeroinitializer
2664}
2665
2666define <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)
2671;
2672  ret <vscale x 4 x float> splat (float 1.0)
2673}
2674
2675define <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
2680;
2681  ret <vscale x 4 x float> zeroinitializer
2682}
2683
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
2686
2687define 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]]
2694;
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]]
2701;
2702entry:
2703  %abs = tail call double @llvm.fabs.f64(double %__x)
2704  ret double %abs
2705}
2706
2707define 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]]
2714;
2715  %shr = lshr i32 %arg, 1
2716  %cast = bitcast i32 %shr to float
2717  ret float %cast
2718}
2719
2720define 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]]
2727;
2728  %shr = lshr i32 %arg, 2
2729  %cast = bitcast i32 %shr to float
2730  ret float %cast
2731}
2732
2733define 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]]
2740;
2741  %or = or i32 %arg, -2147483648
2742  %cast = bitcast i32 %or to float
2743  ret float %cast
2744}
2745
2746define 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]]
2753;
2754  %or = or i32 %arg, 2139095041
2755  %cast = bitcast i32 %or to float
2756  ret float %cast
2757}
2758
2759define 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]]
2766;
2767  %shl = shl i32 %arg, 31
2768  %cast = bitcast i32 %shl to float
2769  ret float %cast
2770}
2771
2772define 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]]
2779;
2780  %or = or i32 %arg, 134217728
2781  %cast = bitcast i32 %or to float
2782  ret float %cast
2783}
2784
2785define 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]]
2793;
2794  %shr = shl i32 %arg, 31
2795  %or = or i32 %shr, 2139095040
2796  %cast = bitcast i32 %or to float
2797  ret float %cast
2798}
2799
2800define 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]]
2807;
2808  %shr = lshr i64 %arg, 1
2809  %cast = bitcast i64 %shr to double
2810  ret double %cast
2811}
2812
2813define 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]]
2820;
2821  %shr = lshr i64 %arg, 2
2822  %cast = bitcast i64 %shr to double
2823  ret double %cast
2824}
2825
2826define 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]]
2833;
2834  %or = or i64 %arg, -9223372036854775808
2835  %cast = bitcast i64 %or to double
2836  ret double %cast
2837}
2838
2839define 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]]
2846;
2847  %or = or i64 %arg, -4503599627370495
2848  %cast = bitcast i64 %or to double
2849  ret double %cast
2850}
2851
2852
2853define 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]]
2860;
2861  %shl = shl i64 %arg, 63
2862  %cast = bitcast i64 %shl to double
2863  ret double %cast
2864}
2865
2866define 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]]
2873;
2874  %or = or i64 %arg, 1152921504606846976
2875  %cast = bitcast i64 %or to double
2876  ret double %cast
2877}
2878
2879define 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]]
2887;
2888  %shr = shl i64 %arg, 63
2889  %or = or i64 %shr, 9218868437227405312
2890  %cast = bitcast i64 %or to double
2891  ret double %cast
2892}
2893
2894
2895define <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]]
2902;
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
2906}
2907
2908define <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]]
2915;
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
2919}
2920
2921define <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]]
2928;
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
2932}
2933
2934define <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]]
2941;
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
2945}
2946
2947define <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]]
2954;
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
2958}
2959
2960define <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]]
2967;
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
2971}
2972
2973declare i64 @_Z13get_global_idj(i32 noundef)
2974
2975attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }
2976attributes #1 = { "denormal-fp-math"="preserve-sign,ieee" }
2977attributes #2 = { "denormal-fp-math"="ieee,preserve-sign" }
2978attributes #3 = { "denormal-fp-math"="positive-zero,positive-zero" }
2979attributes #4 = { "denormal-fp-math"="positive-zero,ieee" }
2980attributes #5 = { "denormal-fp-math"="ieee,positive-zero" }
2981