Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / Attributor / nofpclass.ll
blob442464cde3894823444a76884c5a715d1037e210
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --version 2
2 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-annotate-decl-cs  -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
3 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
5 declare nofpclass(nan) float @ret_nofpclass_nan()
6 declare [2 x [3 x float]] @ret_array()
7 declare float @extern()
8 declare float @extern.f32(float)
9 declare void @extern.use(float)
10 declare void @extern.use.array([2 x [3 x float]])
11 declare void @llvm.assume(i1 noundef)
12 declare void @unknown()
13 declare half @llvm.fabs.f16(half)
14 declare float @llvm.fabs.f32(float)
15 declare void @extern.use.f16(half)
16 declare i1 @llvm.is.fpclass.f32(float, i32 immarg)
17 declare float @llvm.experimental.constrained.sitofp.f32.i32(i32, metadata, metadata)
18 declare float @llvm.experimental.constrained.uitofp.f32.i32(i32, metadata, metadata)
19 declare float @llvm.arithmetic.fence.f32(float)
21 define float @returned_0() {
22 ; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub norm) float @returned_0() {
23 ; CHECK-NEXT:    call void @unknown()
24 ; CHECK-NEXT:    ret float 0.000000e+00
26   call void @unknown()
27   ret float 0.0
30 define float @returned_neg0() {
31 ; CHECK-LABEL: define noundef nofpclass(nan inf pzero sub norm) float @returned_neg0() {
32 ; CHECK-NEXT:    call void @unknown()
33 ; CHECK-NEXT:    ret float -0.000000e+00
35   call void @unknown()
36   ret float -0.0
39 define float @returned_undef() {
40 ; CHECK-LABEL: define nofpclass(all) float @returned_undef() {
41 ; CHECK-NEXT:    call void @unknown()
42 ; CHECK-NEXT:    ret float undef
44   call void @unknown()
45   ret float undef
48 define float @returned_poison() {
49 ; CHECK-LABEL: define nofpclass(all) float @returned_poison() {
50 ; CHECK-NEXT:    call void @unknown()
51 ; CHECK-NEXT:    ret float poison
53   call void @unknown()
54   ret float poison
57 define double @returned_snan() {
58 ; CHECK-LABEL: define noundef nofpclass(qnan inf zero sub norm) double @returned_snan() {
59 ; CHECK-NEXT:    call void @unknown()
60 ; CHECK-NEXT:    ret double 0x7FF0000000000001
62   call void @unknown()
63   ret double 0x7FF0000000000001
66 define double @returned_qnan() {
67 ; CHECK-LABEL: define noundef nofpclass(snan inf zero sub norm) double @returned_qnan() {
68 ; CHECK-NEXT:    call void @unknown()
69 ; CHECK-NEXT:    ret double 0x7FF8000000000000
71   call void @unknown()
72   ret double 0x7FF8000000000000
75 define <2 x double> @returned_zero_vector() {
76 ; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub norm) <2 x double> @returned_zero_vector() {
77 ; CHECK-NEXT:    call void @unknown()
78 ; CHECK-NEXT:    ret <2 x double> zeroinitializer
80   call void @unknown()
81   ret <2 x double> zeroinitializer
84 define <2 x double> @returned_negzero_vector() {
85 ; CHECK-LABEL: define noundef nofpclass(nan inf pzero sub norm) <2 x double> @returned_negzero_vector() {
86 ; CHECK-NEXT:    call void @unknown()
87 ; CHECK-NEXT:    ret <2 x double> <double -0.000000e+00, double -0.000000e+00>
89   call void @unknown()
90   ret <2 x double> <double -0.0, double -0.0>
93 ; Test a vector element that's a constant but not ConstantFP.
94 define <2 x double> @returned_strange_constant_vector_elt() {
95 ; CHECK-LABEL: define <2 x double> @returned_strange_constant_vector_elt() {
96 ; CHECK-NEXT:    call void @unknown()
97 ; CHECK-NEXT:    ret <2 x double> <double -0.000000e+00, double bitcast (i64 ptrtoint (ptr @unknown to i64) to double)>
99   call void @unknown()
100   ret <2 x double> <double -0.0, double bitcast (i64 ptrtoint (ptr @unknown to i64) to double)>
103 ; Test a vector element that's an undef/poison
104 define <3 x double> @returned_undef_constant_vector_elt() {
105 ; CHECK-LABEL: define nofpclass(nan inf pzero sub norm) <3 x double> @returned_undef_constant_vector_elt() {
106 ; CHECK-NEXT:    call void @unknown()
107 ; CHECK-NEXT:    ret <3 x double> <double -0.000000e+00, double poison, double undef>
109   call void @unknown()
110   ret <3 x double> <double -0.0, double poison, double undef>
113 define <2 x double> @returned_qnan_zero_vector() {
114 ; CHECK-LABEL: define noundef nofpclass(snan inf nzero sub norm) <2 x double> @returned_qnan_zero_vector() {
115 ; CHECK-NEXT:    call void @unknown()
116 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double 0.000000e+00>
118   call void @unknown()
119   ret <2 x double> <double 0x7FF8000000000000, double 0.0>
122 ; Return a float trivially nofpclass(nan) (call return attribute)
123 define float @return_nofpclass_nan_decl_return() {
124 ; CHECK-LABEL: define nofpclass(nan) float @return_nofpclass_nan_decl_return() {
125 ; CHECK-NEXT:    [[RET:%.*]] = call nofpclass(nan) float @ret_nofpclass_nan()
126 ; CHECK-NEXT:    ret float [[RET]]
128   %ret = call float @ret_nofpclass_nan()
129   ret float %ret
132 ; Return a float trivially nofpclass(nan) (argument attribute)
133 define float @return_nofpclass_nan_arg(float returned nofpclass(nan) %p) {
134 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
135 ; CHECK-LABEL: define nofpclass(nan) float @return_nofpclass_nan_arg
136 ; CHECK-SAME: (float returned nofpclass(nan) [[P:%.*]]) #[[ATTR3:[0-9]+]] {
137 ; CHECK-NEXT:    ret float [[P]]
139   ret float %p
142 define [2 x [3 x float]] @return_nofpclass_inf_ret_array() {
143 ; CHECK-LABEL: define nofpclass(inf) [2 x [3 x float]] @return_nofpclass_inf_ret_array() {
144 ; CHECK-NEXT:    [[RET:%.*]] = call nofpclass(inf) [2 x [3 x float]] @ret_array()
145 ; CHECK-NEXT:    ret [2 x [3 x float]] [[RET]]
147   %ret = call nofpclass(inf) [2 x [3 x float]]  @ret_array()
148   ret [2 x [3 x float]] %ret
151 define float @returned_nnan_fadd(float %arg0, float %arg1) {
152 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
153 ; CHECK-LABEL: define nofpclass(nan) float @returned_nnan_fadd
154 ; CHECK-SAME: (float nofpclass(nan) [[ARG0:%.*]], float nofpclass(nan) [[ARG1:%.*]]) #[[ATTR3]] {
155 ; CHECK-NEXT:    [[FADD:%.*]] = fadd nnan float [[ARG0]], [[ARG1]]
156 ; CHECK-NEXT:    ret float [[FADD]]
158   %fadd = fadd nnan float %arg0, %arg1
159   ret float %fadd
162 define float @return_nofpclass_nan_callsite() {
163 ; CHECK-LABEL: define nofpclass(nan) float @return_nofpclass_nan_callsite() {
164 ; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan) float @extern()
165 ; CHECK-NEXT:    ret float [[CALL]]
167   %call = call nofpclass(nan) float @extern()
168   ret float %call
171 ; Can union the return classes
172 define nofpclass(inf) float @return_ninf_nofpclass_nan_callsite() {
173 ; CHECK-LABEL: define nofpclass(nan inf) float @return_ninf_nofpclass_nan_callsite() {
174 ; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan) float @extern()
175 ; CHECK-NEXT:    ret float [[CALL]]
177   %call = call nofpclass(nan) float @extern()
178   ret float %call
181 define void @arg_used_by_nofpclass_nan_callsite(float %arg) {
182 ; CHECK-LABEL: define void @arg_used_by_nofpclass_nan_callsite
183 ; CHECK-SAME: (float [[ARG:%.*]]) {
184 ; CHECK-NEXT:    call void @extern.use(float nofpclass(nan) [[ARG]])
185 ; CHECK-NEXT:    ret void
187   call void @extern.use(float nofpclass(nan) %arg)
188   ret void
191 ; Callsite can union the incoming and outgoing
192 define void @ninf_arg_used_by_nofpclass_nan_callsite(float nofpclass(inf) %arg) {
193 ; CHECK-LABEL: define void @ninf_arg_used_by_nofpclass_nan_callsite
194 ; CHECK-SAME: (float nofpclass(inf) [[ARG:%.*]]) {
195 ; CHECK-NEXT:    call void @extern.use(float nofpclass(nan inf) [[ARG]])
196 ; CHECK-NEXT:    ret void
198   call void @extern.use(float nofpclass(nan) %arg)
199   ret void
202 define void @ninf_arg_used_by_callsite_array([2 x [3 x float]] nofpclass(inf) %arg) {
203 ; CHECK-LABEL: define void @ninf_arg_used_by_callsite_array
204 ; CHECK-SAME: ([2 x [3 x float]] nofpclass(inf) [[ARG:%.*]]) {
205 ; CHECK-NEXT:    call void @extern.use.array([2 x [3 x float]] nofpclass(inf) [[ARG]])
206 ; CHECK-NEXT:    ret void
208   call void @extern.use.array([2 x [3 x float]]  %arg)
209   ret void
212 define void @nofpclass_call_use_after_unannotated_use(float %arg) {
213 ; CHECK-LABEL: define void @nofpclass_call_use_after_unannotated_use
214 ; CHECK-SAME: (float [[ARG:%.*]]) {
215 ; CHECK-NEXT:    call void @extern(float [[ARG]]) #[[ATTR17:[0-9]+]]
216 ; CHECK-NEXT:    call void @extern(float nofpclass(nan inf) [[ARG]])
217 ; CHECK-NEXT:    ret void
219   call void @extern(float %arg) willreturn nounwind ; < annotate this use
220   call void @extern(float nofpclass(nan inf) %arg)
221   ret void
224 define float @mutually_recursive0(float %arg) {
225 ; TUNIT: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
226 ; TUNIT-LABEL: define nofpclass(all) float @mutually_recursive0
227 ; TUNIT-SAME: (float [[ARG:%.*]]) #[[ATTR4:[0-9]+]] {
228 ; TUNIT-NEXT:    ret float undef
230 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
231 ; CGSCC-LABEL: define nofpclass(all) float @mutually_recursive0
232 ; CGSCC-SAME: (float [[ARG:%.*]]) #[[ATTR3]] {
233 ; CGSCC-NEXT:    ret float undef
235   %call = call float @mutually_recursive1(float %arg)
236   ret float %call
239 define float @mutually_recursive1(float %arg) {
240 ; TUNIT: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
241 ; TUNIT-LABEL: define nofpclass(all) float @mutually_recursive1
242 ; TUNIT-SAME: (float [[ARG:%.*]]) #[[ATTR4]] {
243 ; TUNIT-NEXT:    ret float undef
245 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
246 ; CGSCC-LABEL: define nofpclass(all) float @mutually_recursive1
247 ; CGSCC-SAME: (float [[ARG:%.*]]) #[[ATTR3]] {
248 ; CGSCC-NEXT:    ret float undef
250   %call = call float @mutually_recursive0(float %arg)
251   ret float %call
254 define float @recursive_phi(ptr %ptr) {
255 ; CHECK-LABEL: define nofpclass(nan) float @recursive_phi
256 ; CHECK-SAME: (ptr nofree [[PTR:%.*]]) {
257 ; CHECK-NEXT:  entry:
258 ; CHECK-NEXT:    [[RET:%.*]] = call nofpclass(nan) float @ret_nofpclass_nan()
259 ; CHECK-NEXT:    br label [[LOOP:%.*]]
260 ; CHECK:       loop:
261 ; CHECK-NEXT:    [[PHI:%.*]] = phi float [ [[RET]], [[ENTRY:%.*]] ], [ [[RET]], [[LOOP]] ]
262 ; CHECK-NEXT:    [[COND:%.*]] = load volatile i1, ptr [[PTR]], align 1
263 ; CHECK-NEXT:    br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
264 ; CHECK:       exit:
265 ; CHECK-NEXT:    ret float [[RET]]
267 entry:
268   %ret = call float @ret_nofpclass_nan()
269   br label %loop
271 loop:
272   %phi = phi float [%ret, %entry], [%phi, %loop]
273   %cond = load volatile i1, ptr %ptr
274   br i1 %cond, label %loop, label %exit
276 exit:
277   ret float %phi
280 ; Should be able to infer nofpclass(nan) return
281 define float @fcmp_uno_check(float %arg) local_unnamed_addr {
282 ; CHECK-LABEL: define float @fcmp_uno_check
283 ; CHECK-SAME: (float [[ARG:%.*]]) local_unnamed_addr {
284 ; CHECK-NEXT:  entry:
285 ; CHECK-NEXT:    [[ISNAN:%.*]] = fcmp uno float [[ARG]], 0.000000e+00
286 ; CHECK-NEXT:    br i1 [[ISNAN]], label [[BB0:%.*]], label [[BB1:%.*]]
287 ; CHECK:       bb0:
288 ; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(nan) float @ret_nofpclass_nan()
289 ; CHECK-NEXT:    br label [[BB1]]
290 ; CHECK:       bb1:
291 ; CHECK-NEXT:    [[PHI:%.*]] = phi float [ [[CALL]], [[BB0]] ], [ [[ARG]], [[ENTRY:%.*]] ]
292 ; CHECK-NEXT:    ret float [[PHI]]
294 entry:
295   %isnan = fcmp uno float %arg, 0.0
296   br i1 %isnan, label %bb0, label %bb1
298 bb0:
299   %call = call float @ret_nofpclass_nan()
300   br label %bb1
302 bb1:
303   %phi = phi float [ %call, %bb0 ], [ %arg, %entry ]
304   ret float %phi
307 ; Should be able to infer nofpclass(nan) on %arg use
308 define void @fcmp_ord_guard_callsite_arg(float %arg) {
309 ; CHECK-LABEL: define void @fcmp_ord_guard_callsite_arg
310 ; CHECK-SAME: (float [[ARG:%.*]]) {
311 ; CHECK-NEXT:  entry:
312 ; CHECK-NEXT:    [[IS_NOT_NAN:%.*]] = fcmp ord float [[ARG]], 0.000000e+00
313 ; CHECK-NEXT:    br i1 [[IS_NOT_NAN]], label [[BB0:%.*]], label [[BB1:%.*]]
314 ; CHECK:       bb0:
315 ; CHECK-NEXT:    call void @extern.use(float [[ARG]])
316 ; CHECK-NEXT:    br label [[BB1]]
317 ; CHECK:       bb1:
318 ; CHECK-NEXT:    ret void
320 entry:
321   %is.not.nan = fcmp ord float %arg, 0.0
322   br i1 %is.not.nan, label %bb0, label %bb1
324 bb0:
325   call void @extern.use(float %arg)
326   br label %bb1
328 bb1:
329   ret void
332 ; Should be able to infer nofpclass on both %arg uses
333 define float @fcmp_ord_assume_callsite_arg_return(float %arg) {
334 ; CHECK-LABEL: define nofpclass(nan) float @fcmp_ord_assume_callsite_arg_return
335 ; CHECK-SAME: (float returned nofpclass(nan) [[ARG:%.*]]) {
336 ; CHECK-NEXT:  entry:
337 ; CHECK-NEXT:    [[IS_NOT_NAN:%.*]] = fcmp ord float [[ARG]], 0.000000e+00
338 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_NOT_NAN]]) #[[ATTR18:[0-9]+]]
339 ; CHECK-NEXT:    call void @extern.use(float nofpclass(nan) [[ARG]])
340 ; CHECK-NEXT:    ret float [[ARG]]
342 entry:
343   %is.not.nan = fcmp ord float %arg, 0.0
344   call void @llvm.assume(i1 %is.not.nan)
345   call void @extern.use(float %arg)
346   ret float %arg
349 define internal float @returned_dead() {
350 ; CHECK-LABEL: define internal nofpclass(nan inf nzero sub norm) float @returned_dead() {
351 ; CHECK-NEXT:    call void @unknown()
352 ; CHECK-NEXT:    ret float undef
354   call void @unknown()
355   ret float 0.0
358 define void @returned_dead_caller() {
359 ; CHECK-LABEL: define void @returned_dead_caller() {
360 ; CHECK-NEXT:    [[TMP1:%.*]] = call float @returned_dead()
361 ; CHECK-NEXT:    ret void
363   call float @returned_dead()
364   ret void
367 define internal float @only_nofpclass_inf_callers(float %arg) {
368 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
369 ; CHECK-LABEL: define internal float @only_nofpclass_inf_callers
370 ; CHECK-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR3]] {
371 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
372 ; CHECK-NEXT:    ret float [[ADD]]
374   %add = fadd float %arg, %arg
375   ret float %add
378 define float @call_noinf_0(float nofpclass(inf) %arg) {
379 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
380 ; TUNIT-LABEL: define float @call_noinf_0
381 ; TUNIT-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR3]] {
382 ; TUNIT-NEXT:    [[RESULT:%.*]] = call float @only_nofpclass_inf_callers(float nofpclass(inf) [[ARG]]) #[[ATTR19:[0-9]+]]
383 ; TUNIT-NEXT:    ret float [[RESULT]]
385 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
386 ; CGSCC-LABEL: define float @call_noinf_0
387 ; CGSCC-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR4:[0-9]+]] {
388 ; CGSCC-NEXT:    [[RESULT:%.*]] = call float @only_nofpclass_inf_callers(float nofpclass(inf) [[ARG]]) #[[ATTR19:[0-9]+]]
389 ; CGSCC-NEXT:    ret float [[RESULT]]
391   %result = call float @only_nofpclass_inf_callers(float %arg)
392   ret float %result
395 define float @call_noinf_1(float %arg) {
396 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
397 ; TUNIT-LABEL: define float @call_noinf_1
398 ; TUNIT-SAME: (float [[ARG:%.*]]) #[[ATTR3]] {
399 ; TUNIT-NEXT:    [[RESULT:%.*]] = call float @only_nofpclass_inf_callers(float nofpclass(inf) [[ARG]]) #[[ATTR19]]
400 ; TUNIT-NEXT:    ret float [[RESULT]]
402 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
403 ; CGSCC-LABEL: define float @call_noinf_1
404 ; CGSCC-SAME: (float [[ARG:%.*]]) #[[ATTR4]] {
405 ; CGSCC-NEXT:    [[RESULT:%.*]] = call float @only_nofpclass_inf_callers(float nofpclass(inf) [[ARG]]) #[[ATTR19]]
406 ; CGSCC-NEXT:    ret float [[RESULT]]
408   %result = call float @only_nofpclass_inf_callers(float nofpclass(inf) %arg)
409   ret float %result
412 ; TODO: Should be able to infer nofpclass(inf) on return
413 define internal float @only_nofpclass_inf_return_users(float %arg) {
414 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
415 ; CHECK-LABEL: define internal float @only_nofpclass_inf_return_users
416 ; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR3]] {
417 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
418 ; CHECK-NEXT:    ret float [[ADD]]
420   %add = fadd float %arg, %arg
421   ret float %add
424 define float @call_noinf_return_0(float %arg) {
425 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
426 ; TUNIT-LABEL: define nofpclass(inf) float @call_noinf_return_0
427 ; TUNIT-SAME: (float [[ARG:%.*]]) #[[ATTR3]] {
428 ; TUNIT-NEXT:    [[RESULT:%.*]] = call nofpclass(inf) float @only_nofpclass_inf_return_users(float [[ARG]]) #[[ATTR19]]
429 ; TUNIT-NEXT:    ret float [[RESULT]]
431 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
432 ; CGSCC-LABEL: define nofpclass(inf) float @call_noinf_return_0
433 ; CGSCC-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR4]] {
434 ; CGSCC-NEXT:    [[RESULT:%.*]] = call nofpclass(inf) float @only_nofpclass_inf_return_users(float nofpclass(inf) [[ARG]]) #[[ATTR19]]
435 ; CGSCC-NEXT:    ret float [[RESULT]]
437   %result = call nofpclass(inf) float @only_nofpclass_inf_return_users(float %arg)
438   ret float %result
441 define float @call_noinf_return_1(float %arg) {
442 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
443 ; TUNIT-LABEL: define nofpclass(inf) float @call_noinf_return_1
444 ; TUNIT-SAME: (float [[ARG:%.*]]) #[[ATTR3]] {
445 ; TUNIT-NEXT:    [[RESULT:%.*]] = call nofpclass(inf) float @only_nofpclass_inf_return_users(float [[ARG]]) #[[ATTR19]]
446 ; TUNIT-NEXT:    ret float [[RESULT]]
448 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
449 ; CGSCC-LABEL: define nofpclass(inf) float @call_noinf_return_1
450 ; CGSCC-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR4]] {
451 ; CGSCC-NEXT:    [[RESULT:%.*]] = call nofpclass(inf) float @only_nofpclass_inf_return_users(float nofpclass(inf) [[ARG]]) #[[ATTR19]]
452 ; CGSCC-NEXT:    ret float [[RESULT]]
454   %result = call nofpclass(inf) float @only_nofpclass_inf_return_users(float %arg)
455   ret float %result
458 define float @fcmp_olt_assume_one_0_callsite_arg_return(float %arg) {
459 ; CHECK-LABEL: define nofpclass(nan zero) float @fcmp_olt_assume_one_0_callsite_arg_return
460 ; CHECK-SAME: (float returned nofpclass(nan zero) [[ARG:%.*]]) {
461 ; CHECK-NEXT:  entry:
462 ; CHECK-NEXT:    [[IS_NOT_ZERO_OR_NAN:%.*]] = fcmp one float [[ARG]], 0.000000e+00
463 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_NOT_ZERO_OR_NAN]]) #[[ATTR18]]
464 ; CHECK-NEXT:    call void @extern.use(float nofpclass(nan zero) [[ARG]])
465 ; CHECK-NEXT:    ret float [[ARG]]
467 entry:
468   %is.not.zero.or.nan = fcmp one float %arg, 0.0
469   call void @llvm.assume(i1 %is.not.zero.or.nan)
470   call void @extern.use(float %arg)
471   ret float %arg
474 define float @fcmp_olt_assume_une_0_callsite_arg_return(float %arg) {
475 ; CHECK-LABEL: define nofpclass(zero) float @fcmp_olt_assume_une_0_callsite_arg_return
476 ; CHECK-SAME: (float returned nofpclass(zero) [[ARG:%.*]]) {
477 ; CHECK-NEXT:  entry:
478 ; CHECK-NEXT:    [[IS_NOT_ZERO_OR_NAN:%.*]] = fcmp une float [[ARG]], 0.000000e+00
479 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_NOT_ZERO_OR_NAN]]) #[[ATTR18]]
480 ; CHECK-NEXT:    call void @extern.use(float nofpclass(zero) [[ARG]])
481 ; CHECK-NEXT:    ret float [[ARG]]
483 entry:
484   %is.not.zero.or.nan = fcmp une float %arg, 0.0
485   call void @llvm.assume(i1 %is.not.zero.or.nan)
486   call void @extern.use(float %arg)
487   ret float %arg
490 define half @fcmp_assume_issubnormal_callsite_arg_return(half %arg) {
491 ; CHECK-LABEL: define nofpclass(nan inf nzero nsub norm) half @fcmp_assume_issubnormal_callsite_arg_return
492 ; CHECK-SAME: (half returned nofpclass(nan inf nzero nsub norm) [[ARG:%.*]]) {
493 ; CHECK-NEXT:  entry:
494 ; CHECK-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) half @llvm.fabs.f16(half nofpclass(nan inf nzero nsub norm) [[ARG]]) #[[ATTR20:[0-9]+]]
495 ; CHECK-NEXT:    [[IS_SUBNORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400
496 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_SUBNORMAL]]) #[[ATTR18]]
497 ; CHECK-NEXT:    call void @extern.use.f16(half nofpclass(nan inf nzero nsub norm) [[ARG]])
498 ; CHECK-NEXT:    ret half [[ARG]]
500 entry:
501   %fabs = call half @llvm.fabs.f16(half %arg)
502   %is.subnormal = fcmp olt half %fabs, 0xH0400
503   call void @llvm.assume(i1 %is.subnormal)
504   call void @extern.use.f16(half %arg)
505   ret half %arg
508 ; Assume is after the call, shouldn't mark callsite.
509 define half @fcmp_assume_not_inf_after_call(half %arg) {
510 ; CHECK-LABEL: define half @fcmp_assume_not_inf_after_call
511 ; CHECK-SAME: (half returned [[ARG:%.*]]) {
512 ; CHECK-NEXT:  entry:
513 ; CHECK-NEXT:    call void @extern.use.f16(half [[ARG]])
514 ; CHECK-NEXT:    [[NOT_INF:%.*]] = fcmp oeq half [[ARG]], 0xH7C00
515 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[NOT_INF]])
516 ; CHECK-NEXT:    ret half [[ARG]]
518 entry:
519   call void @extern.use.f16(half %arg)
520   %not.inf = fcmp oeq half %arg, 0xH7C00
521   call void @llvm.assume(i1 %not.inf)
522   ret half %arg
525 ; Assume not subnormal or zero, and not infinity
526 define half @fcmp_assume2_callsite_arg_return(half %arg) {
527 ; CHECK-LABEL: define nofpclass(nan inf zero sub nnorm) half @fcmp_assume2_callsite_arg_return
528 ; CHECK-SAME: (half returned nofpclass(nan inf zero sub nnorm) [[ARG:%.*]]) {
529 ; CHECK-NEXT:  entry:
530 ; CHECK-NEXT:    [[FABS:%.*]] = call nofpclass(nan ninf nzero nsub nnorm) half @llvm.fabs.f16(half nofpclass(nan inf zero sub nnorm) [[ARG]]) #[[ATTR20]]
531 ; CHECK-NEXT:    [[NOT_SUBNORMAL_OR_ZERO:%.*]] = fcmp oge half [[FABS]], 0xH0400
532 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[NOT_SUBNORMAL_OR_ZERO]]) #[[ATTR18]]
533 ; CHECK-NEXT:    [[NOT_INF:%.*]] = fcmp one half [[ARG]], 0xH7C00
534 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[NOT_INF]]) #[[ATTR18]]
535 ; CHECK-NEXT:    call void @extern.use.f16(half nofpclass(nan inf zero sub nnorm) [[ARG]])
536 ; CHECK-NEXT:    ret half [[ARG]]
538 entry:
539   %fabs = call half @llvm.fabs.f16(half %arg)
540   %not.subnormal.or.zero = fcmp oge half %fabs, 0xH0400
541   call void @llvm.assume(i1 %not.subnormal.or.zero)
543   %not.inf = fcmp one half %arg, 0xH7C00
544   call void @llvm.assume(i1 %not.inf)
546   call void @extern.use.f16(half %arg)
547   ret half %arg
550 define float @is_fpclass_assume_arg_return(float %arg) {
551 ; CHECK-LABEL: define nofpclass(nan pinf pzero sub nnorm) float @is_fpclass_assume_arg_return
552 ; CHECK-SAME: (float returned nofpclass(nan pinf pzero sub nnorm) [[ARG:%.*]]) {
553 ; CHECK-NEXT:  entry:
554 ; CHECK-NEXT:    [[CLASS_TEST:%.*]] = call i1 @llvm.is.fpclass.f32(float nofpclass(nan pinf pzero sub nnorm) [[ARG]], i32 noundef 292) #[[ATTR20]]
555 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[CLASS_TEST]]) #[[ATTR18]]
556 ; CHECK-NEXT:    call void @extern.use(float nofpclass(nan pinf pzero sub nnorm) [[ARG]])
557 ; CHECK-NEXT:    ret float [[ARG]]
559 entry:
560   %class.test = call i1 @llvm.is.fpclass.f32(float %arg, i32 292)
561   call void @llvm.assume(i1 %class.test)
562   call void @extern.use(float %arg)
563   ret float %arg
566 ; Make sure we don't get confused by looking at an unrelated assume
567 ; based on the fabs of the value.
568 define half @assume_fcmp_fabs_with_other_fabs_assume(half %arg) {
569 ; CHECK-LABEL: define nofpclass(nan inf zero nsub norm) half @assume_fcmp_fabs_with_other_fabs_assume
570 ; CHECK-SAME: (half returned nofpclass(nan inf zero nsub norm) [[ARG:%.*]]) {
571 ; CHECK-NEXT:  entry:
572 ; CHECK-NEXT:    [[FABS:%.*]] = call nofpclass(nan inf zero nsub norm) half @llvm.fabs.f16(half nofpclass(nan inf zero nsub norm) [[ARG]]) #[[ATTR20]]
573 ; CHECK-NEXT:    [[UNRELATED_FABS:%.*]] = fcmp one half [[FABS]], 0xH0000
574 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[UNRELATED_FABS]]) #[[ATTR18]]
575 ; CHECK-NEXT:    [[IS_SUBNORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400
576 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_SUBNORMAL]]) #[[ATTR18]]
577 ; CHECK-NEXT:    call void @extern.use.f16(half nofpclass(nan inf zero nsub norm) [[ARG]])
578 ; CHECK-NEXT:    call void @extern.use.f16(half nofpclass(nan inf zero nsub norm) [[FABS]])
579 ; CHECK-NEXT:    ret half [[ARG]]
581 entry:
583   %fabs = call half @llvm.fabs.f16(half %arg)
584   %unrelated.fabs = fcmp one half %fabs, 0.0
585   call void @llvm.assume(i1 %unrelated.fabs)
586   %is.subnormal = fcmp olt half %fabs, 0xH0400
587   call void @llvm.assume(i1 %is.subnormal)
588   call void @extern.use.f16(half %arg)
589   call void @extern.use.f16(half %fabs)
590   ret half %arg
593 ; Make sure if looking through the fabs finds a different source
594 ; value, we still identify a test mask by ignoring the fabs
595 define half @assume_fcmp_fabs_with_other_fabs_assume_fallback(half %arg) {
596 ; CHECK-LABEL: define nofpclass(nan inf nzero sub norm) half @assume_fcmp_fabs_with_other_fabs_assume_fallback
597 ; CHECK-SAME: (half returned nofpclass(nan inf nzero sub norm) [[ARG:%.*]]) {
598 ; CHECK-NEXT:  entry:
599 ; CHECK-NEXT:    [[FABS:%.*]] = call nofpclass(nan inf nzero sub norm) half @llvm.fabs.f16(half nofpclass(nan inf nzero sub norm) [[ARG]]) #[[ATTR20]]
600 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR18]]
601 ; CHECK-NEXT:    [[UNRELATED_FABS:%.*]] = fcmp oeq half [[FABS]], 0xH0000
602 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[UNRELATED_FABS]]) #[[ATTR18]]
603 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR18]]
604 ; CHECK-NEXT:    call void @extern.use.f16(half nofpclass(nan inf nzero sub norm) [[ARG]])
605 ; CHECK-NEXT:    call void @extern.use.f16(half nofpclass(nan inf nzero sub norm) [[FABS]])
606 ; CHECK-NEXT:    ret half [[ARG]]
608 entry:
610   %fabs = call half @llvm.fabs.f16(half %arg)
612   %one.inf = fcmp one half %arg, 0xH7C00
613   call void @llvm.assume(i1 %one.inf)
615   %unrelated.fabs = fcmp oeq half %fabs, 0.0
616   call void @llvm.assume(i1 %unrelated.fabs)
618   %is.subnormal = fcmp olt half %fabs, 0xH0400
619   call void @llvm.assume(i1 %is.subnormal)
620   call void @extern.use.f16(half %arg)
621   call void @extern.use.f16(half %fabs)
622   ret half %arg
625 define float @assume_bundles(i1 %c, float %ret) {
626 ; CHECK-LABEL: define float @assume_bundles
627 ; CHECK-SAME: (i1 noundef [[C:%.*]], float returned [[RET:%.*]]) {
628 ; CHECK-NEXT:  entry:
629 ; CHECK-NEXT:    br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
630 ; CHECK:       A:
631 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR18]] [ "nofpclass"(float [[RET]], i32 3) ]
632 ; CHECK-NEXT:    call void @extern.use(float nofpclass(nan) [[RET]])
633 ; CHECK-NEXT:    ret float [[RET]]
634 ; CHECK:       B:
635 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) [ "nofpclass"(float [[RET]], i32 12) ]
636 ; CHECK-NEXT:    call void @extern.use(float nofpclass(ninf nnorm) [[RET]])
637 ; CHECK-NEXT:    ret float [[RET]]
639 entry:
640   br i1 %c, label %A, label %B
643   call void @llvm.assume(i1 true) [ "nofpclass"(float %ret, i32 3) ]
644   call void @extern.use(float %ret)
645   ret float %ret
648   call void @llvm.assume(i1 true) [ "nofpclass"(float %ret, i32 12) ]
649   call void @extern.use(float %ret)
650   ret float %ret
653 define float @returned_load(ptr %ptr) {
654 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
655 ; CHECK-LABEL: define float @returned_load
656 ; CHECK-SAME: (ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[PTR:%.*]]) #[[ATTR5:[0-9]+]] {
657 ; CHECK-NEXT:    [[LOAD:%.*]] = load float, ptr [[PTR]], align 4
658 ; CHECK-NEXT:    ret float [[LOAD]]
660   %load = load float, ptr %ptr
661   ret float %load
664 define float @pass_nofpclass_inf_through_memory(float nofpclass(inf) %arg) {
665 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
666 ; TUNIT-LABEL: define float @pass_nofpclass_inf_through_memory
667 ; TUNIT-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR3]] {
668 ; TUNIT-NEXT:    [[ALLOCA:%.*]] = alloca float, align 4
669 ; TUNIT-NEXT:    store float [[ARG]], ptr [[ALLOCA]], align 4
670 ; TUNIT-NEXT:    [[RET:%.*]] = call float @returned_load(ptr noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ALLOCA]]) #[[ATTR21:[0-9]+]]
671 ; TUNIT-NEXT:    ret float [[RET]]
673 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
674 ; CGSCC-LABEL: define float @pass_nofpclass_inf_through_memory
675 ; CGSCC-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR4]] {
676 ; CGSCC-NEXT:    [[ALLOCA:%.*]] = alloca float, align 4
677 ; CGSCC-NEXT:    store float [[ARG]], ptr [[ALLOCA]], align 4
678 ; CGSCC-NEXT:    [[RET:%.*]] = call float @returned_load(ptr noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ALLOCA]]) #[[ATTR21:[0-9]+]]
679 ; CGSCC-NEXT:    ret float [[RET]]
681   %alloca = alloca float
682   store float %arg, ptr %alloca
683   %ret = call float @returned_load(ptr %alloca)
684   ret float %ret
687 define float @returned_fabs(float %x) {
688 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
689 ; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs
690 ; TUNIT-SAME: (float nofpclass(ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
691 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf nzero nsub nnorm) [[X]]) #[[ATTR22:[0-9]+]]
692 ; TUNIT-NEXT:    ret float [[FABS]]
694 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
695 ; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs
696 ; CGSCC-SAME: (float nofpclass(ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
697 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf nzero nsub nnorm) [[X]]) #[[ATTR19]]
698 ; CGSCC-NEXT:    ret float [[FABS]]
700   %fabs = call float @llvm.fabs.f32(float %x)
701   ret float %fabs
704 define float @returned_fabs_nosnan(float nofpclass(snan) %x) {
705 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
706 ; TUNIT-LABEL: define nofpclass(snan ninf nzero nsub nnorm) float @returned_fabs_nosnan
707 ; TUNIT-SAME: (float nofpclass(snan ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
708 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(snan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(snan ninf nzero nsub nnorm) [[X]]) #[[ATTR22]]
709 ; TUNIT-NEXT:    ret float [[FABS]]
711 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
712 ; CGSCC-LABEL: define nofpclass(snan ninf nzero nsub nnorm) float @returned_fabs_nosnan
713 ; CGSCC-SAME: (float nofpclass(snan ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
714 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(snan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(snan ninf nzero nsub nnorm) [[X]]) #[[ATTR19]]
715 ; CGSCC-NEXT:    ret float [[FABS]]
717   %fabs = call float @llvm.fabs.f32(float %x)
718   ret float %fabs
721 define float @returned_fabs_noqnan(float nofpclass(qnan) %x) {
722 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
723 ; TUNIT-LABEL: define nofpclass(qnan ninf nzero nsub nnorm) float @returned_fabs_noqnan
724 ; TUNIT-SAME: (float nofpclass(qnan ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
725 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(qnan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(qnan ninf nzero nsub nnorm) [[X]]) #[[ATTR22]]
726 ; TUNIT-NEXT:    ret float [[FABS]]
728 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
729 ; CGSCC-LABEL: define nofpclass(qnan ninf nzero nsub nnorm) float @returned_fabs_noqnan
730 ; CGSCC-SAME: (float nofpclass(qnan ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
731 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(qnan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(qnan ninf nzero nsub nnorm) [[X]]) #[[ATTR19]]
732 ; CGSCC-NEXT:    ret float [[FABS]]
734   %fabs = call float @llvm.fabs.f32(float %x)
735   ret float %fabs
738 define float @returned_fabs_nonan(float nofpclass(nan) %x) {
739 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
740 ; TUNIT-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @returned_fabs_nonan
741 ; TUNIT-SAME: (float nofpclass(nan ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
742 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(nan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nan ninf nzero nsub nnorm) [[X]]) #[[ATTR22]]
743 ; TUNIT-NEXT:    ret float [[FABS]]
745 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
746 ; CGSCC-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @returned_fabs_nonan
747 ; CGSCC-SAME: (float nofpclass(nan ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
748 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(nan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nan ninf nzero nsub nnorm) [[X]]) #[[ATTR19]]
749 ; CGSCC-NEXT:    ret float [[FABS]]
751   %fabs = call float @llvm.fabs.f32(float %x)
752   ret float %fabs
755 define float @returned_fabs_noinf(float nofpclass(inf) %x) {
756 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
757 ; TUNIT-LABEL: define nofpclass(inf nzero nsub nnorm) float @returned_fabs_noinf
758 ; TUNIT-SAME: (float nofpclass(inf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
759 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(inf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(inf nzero nsub nnorm) [[X]]) #[[ATTR22]]
760 ; TUNIT-NEXT:    ret float [[FABS]]
762 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
763 ; CGSCC-LABEL: define nofpclass(inf nzero nsub nnorm) float @returned_fabs_noinf
764 ; CGSCC-SAME: (float nofpclass(inf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
765 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(inf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(inf nzero nsub nnorm) [[X]]) #[[ATTR19]]
766 ; CGSCC-NEXT:    ret float [[FABS]]
768   %fabs = call float @llvm.fabs.f32(float %x)
769   ret float %fabs
772 define float @returned_fabs_nopos(float nofpclass(psub pnorm pinf) %x) {
773 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
774 ; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nopos
775 ; TUNIT-SAME: (float nofpclass(inf nzero sub norm) [[X:%.*]]) #[[ATTR3]] {
776 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(inf nzero sub norm) [[X]]) #[[ATTR22]]
777 ; TUNIT-NEXT:    ret float [[FABS]]
779 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
780 ; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nopos
781 ; CGSCC-SAME: (float nofpclass(inf nzero sub norm) [[X:%.*]]) #[[ATTR3]] {
782 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(inf nzero sub norm) [[X]]) #[[ATTR19]]
783 ; CGSCC-NEXT:    ret float [[FABS]]
785   %fabs = call float @llvm.fabs.f32(float %x)
786   ret float %fabs
789 define float @returned_fabs_nopos_nopzero(float nofpclass(psub pnorm pinf pzero) %x) {
790 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
791 ; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nopos_nopzero
792 ; TUNIT-SAME: (float nofpclass(inf zero sub norm) [[X:%.*]]) #[[ATTR3]] {
793 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(inf zero sub norm) [[X]]) #[[ATTR22]]
794 ; TUNIT-NEXT:    ret float [[FABS]]
796 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
797 ; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nopos_nopzero
798 ; CGSCC-SAME: (float nofpclass(inf zero sub norm) [[X:%.*]]) #[[ATTR3]] {
799 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(inf zero sub norm) [[X]]) #[[ATTR19]]
800 ; CGSCC-NEXT:    ret float [[FABS]]
802   %fabs = call float @llvm.fabs.f32(float %x)
803   ret float %fabs
806 define float @returned_fabs_nopos_nozero(float nofpclass(psub pnorm pinf zero) %x) {
807 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
808 ; TUNIT-LABEL: define nofpclass(ninf zero nsub nnorm) float @returned_fabs_nopos_nozero
809 ; TUNIT-SAME: (float nofpclass(inf zero sub norm) [[X:%.*]]) #[[ATTR3]] {
810 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf zero nsub nnorm) float @llvm.fabs.f32(float nofpclass(inf zero sub norm) [[X]]) #[[ATTR22]]
811 ; TUNIT-NEXT:    ret float [[FABS]]
813 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
814 ; CGSCC-LABEL: define nofpclass(ninf zero nsub nnorm) float @returned_fabs_nopos_nozero
815 ; CGSCC-SAME: (float nofpclass(inf zero sub norm) [[X:%.*]]) #[[ATTR3]] {
816 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf zero nsub nnorm) float @llvm.fabs.f32(float nofpclass(inf zero sub norm) [[X]]) #[[ATTR19]]
817 ; CGSCC-NEXT:    ret float [[FABS]]
819   %fabs = call float @llvm.fabs.f32(float %x)
820   ret float %fabs
823 define float @returned_fabs_nopos_nonan(float nofpclass(psub pnorm pinf nan) %x) {
824 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
825 ; TUNIT-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @returned_fabs_nopos_nonan
826 ; TUNIT-SAME: (float nofpclass(nan inf nzero sub norm) [[X:%.*]]) #[[ATTR3]] {
827 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(nan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nan inf nzero sub norm) [[X]]) #[[ATTR22]]
828 ; TUNIT-NEXT:    ret float [[FABS]]
830 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
831 ; CGSCC-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @returned_fabs_nopos_nonan
832 ; CGSCC-SAME: (float nofpclass(nan inf nzero sub norm) [[X:%.*]]) #[[ATTR3]] {
833 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(nan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nan inf nzero sub norm) [[X]]) #[[ATTR19]]
834 ; CGSCC-NEXT:    ret float [[FABS]]
836   %fabs = call float @llvm.fabs.f32(float %x)
837   ret float %fabs
840 define float @returned_fabs_noneg(float nofpclass(nsub nnorm ninf) %x) {
841 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
842 ; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_noneg
843 ; TUNIT-SAME: (float nofpclass(ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
844 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf nzero nsub nnorm) [[X]]) #[[ATTR22]]
845 ; TUNIT-NEXT:    ret float [[FABS]]
847 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
848 ; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_noneg
849 ; CGSCC-SAME: (float nofpclass(ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
850 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf nzero nsub nnorm) [[X]]) #[[ATTR19]]
851 ; CGSCC-NEXT:    ret float [[FABS]]
853   %fabs = call float @llvm.fabs.f32(float %x)
854   ret float %fabs
857 define float @returned_fabs_noneg_nonzero(float nofpclass(nsub nnorm ninf nzero) %x) {
858 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
859 ; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_noneg_nonzero
860 ; TUNIT-SAME: (float nofpclass(ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
861 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf nzero nsub nnorm) [[X]]) #[[ATTR22]]
862 ; TUNIT-NEXT:    ret float [[FABS]]
864 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
865 ; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_noneg_nonzero
866 ; CGSCC-SAME: (float nofpclass(ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
867 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf nzero nsub nnorm) [[X]]) #[[ATTR19]]
868 ; CGSCC-NEXT:    ret float [[FABS]]
870   %fabs = call float @llvm.fabs.f32(float %x)
871   ret float %fabs
874 define float @returned_fabs_noneg_nozero(float nofpclass(nsub nnorm ninf zero) %x) {
875 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
876 ; TUNIT-LABEL: define nofpclass(ninf zero nsub nnorm) float @returned_fabs_noneg_nozero
877 ; TUNIT-SAME: (float nofpclass(ninf zero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
878 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf zero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf zero nsub nnorm) [[X]]) #[[ATTR22]]
879 ; TUNIT-NEXT:    ret float [[FABS]]
881 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
882 ; CGSCC-LABEL: define nofpclass(ninf zero nsub nnorm) float @returned_fabs_noneg_nozero
883 ; CGSCC-SAME: (float nofpclass(ninf zero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
884 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf zero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf zero nsub nnorm) [[X]]) #[[ATTR19]]
885 ; CGSCC-NEXT:    ret float [[FABS]]
887   %fabs = call float @llvm.fabs.f32(float %x)
888   ret float %fabs
891 define float @returned_fabs_noneg_nonan(float nofpclass(nsub nnorm ninf nan) %x) {
892 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
893 ; TUNIT-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @returned_fabs_noneg_nonan
894 ; TUNIT-SAME: (float nofpclass(nan ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
895 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(nan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nan ninf nzero nsub nnorm) [[X]]) #[[ATTR22]]
896 ; TUNIT-NEXT:    ret float [[FABS]]
898 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
899 ; CGSCC-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @returned_fabs_noneg_nonan
900 ; CGSCC-SAME: (float nofpclass(nan ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
901 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(nan ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(nan ninf nzero nsub nnorm) [[X]]) #[[ATTR19]]
902 ; CGSCC-NEXT:    ret float [[FABS]]
904   %fabs = call float @llvm.fabs.f32(float %x)
905   ret float %fabs
908 define float @returned_fabs_nonsub_nopnorm_nonzero(float nofpclass(nsub pnorm nzero) %x) {
909 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
910 ; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nonsub_nopnorm_nonzero
911 ; TUNIT-SAME: (float nofpclass(ninf nzero nsub norm) [[X:%.*]]) #[[ATTR3]] {
912 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf nzero nsub norm) [[X]]) #[[ATTR22]]
913 ; TUNIT-NEXT:    ret float [[FABS]]
915 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
916 ; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nonsub_nopnorm_nonzero
917 ; CGSCC-SAME: (float nofpclass(ninf nzero nsub norm) [[X:%.*]]) #[[ATTR3]] {
918 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf nzero nsub norm) [[X]]) #[[ATTR19]]
919 ; CGSCC-NEXT:    ret float [[FABS]]
921   %fabs = call float @llvm.fabs.f32(float %x)
922   ret float %fabs
925 define float @returned_fabs_nopsub_nonnorm_nopzero(float nofpclass(psub nnorm pzero) %x) {
926 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
927 ; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nopsub_nonnorm_nopzero
928 ; TUNIT-SAME: (float nofpclass(ninf zero sub nnorm) [[X:%.*]]) #[[ATTR3]] {
929 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf zero sub nnorm) [[X]]) #[[ATTR22]]
930 ; TUNIT-NEXT:    ret float [[FABS]]
932 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
933 ; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nopsub_nonnorm_nopzero
934 ; CGSCC-SAME: (float nofpclass(ninf zero sub nnorm) [[X:%.*]]) #[[ATTR3]] {
935 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf zero sub nnorm) [[X]]) #[[ATTR19]]
936 ; CGSCC-NEXT:    ret float [[FABS]]
938   %fabs = call float @llvm.fabs.f32(float %x)
939   ret float %fabs
942 define float @returned_fabs_nonnorm_nozero(float nofpclass(nnorm nzero) %x) {
943 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
944 ; TUNIT-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nonnorm_nozero
945 ; TUNIT-SAME: (float nofpclass(ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
946 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf nzero nsub nnorm) [[X]]) #[[ATTR22]]
947 ; TUNIT-NEXT:    ret float [[FABS]]
949 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
950 ; CGSCC-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fabs_nonnorm_nozero
951 ; CGSCC-SAME: (float nofpclass(ninf nzero nsub nnorm) [[X:%.*]]) #[[ATTR3]] {
952 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float nofpclass(ninf nzero nsub nnorm) [[X]]) #[[ATTR19]]
953 ; CGSCC-NEXT:    ret float [[FABS]]
955   %fabs = call float @llvm.fabs.f32(float %x)
956   ret float %fabs
959 define float @returned_fneg(float %x) {
960 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
961 ; CHECK-LABEL: define float @returned_fneg
962 ; CHECK-SAME: (float [[X:%.*]]) #[[ATTR3]] {
963 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
964 ; CHECK-NEXT:    ret float [[FNEG]]
966   %fneg = fneg float %x
967   ret float %fneg
970 define float @returned_fneg_nosnan(float nofpclass(snan) %x) {
971 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
972 ; CHECK-LABEL: define nofpclass(snan) float @returned_fneg_nosnan
973 ; CHECK-SAME: (float nofpclass(snan) [[X:%.*]]) #[[ATTR3]] {
974 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
975 ; CHECK-NEXT:    ret float [[FNEG]]
977   %fneg = fneg float %x
978   ret float %fneg
981 define float @returned_fneg_noqnan(float nofpclass(qnan) %x) {
982 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
983 ; CHECK-LABEL: define nofpclass(qnan) float @returned_fneg_noqnan
984 ; CHECK-SAME: (float nofpclass(qnan) [[X:%.*]]) #[[ATTR3]] {
985 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
986 ; CHECK-NEXT:    ret float [[FNEG]]
988   %fneg = fneg float %x
989   ret float %fneg
992 define float @returned_fneg_nosnan_ninf_flag(float nofpclass(snan) %x) {
993 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
994 ; CHECK-LABEL: define nofpclass(snan inf) float @returned_fneg_nosnan_ninf_flag
995 ; CHECK-SAME: (float nofpclass(snan inf) [[X:%.*]]) #[[ATTR3]] {
996 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg ninf float [[X]]
997 ; CHECK-NEXT:    ret float [[FNEG]]
999   %fneg = fneg ninf float %x
1000   ret float %fneg
1003 define float @returned_fneg_nonan(float nofpclass(nan) %x) {
1004 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1005 ; CHECK-LABEL: define nofpclass(nan) float @returned_fneg_nonan
1006 ; CHECK-SAME: (float nofpclass(nan) [[X:%.*]]) #[[ATTR3]] {
1007 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
1008 ; CHECK-NEXT:    ret float [[FNEG]]
1010   %fneg = fneg float %x
1011   ret float %fneg
1014 define float @returned_fneg_noinf(float nofpclass(inf) %x) {
1015 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1016 ; CHECK-LABEL: define nofpclass(inf) float @returned_fneg_noinf
1017 ; CHECK-SAME: (float nofpclass(inf) [[X:%.*]]) #[[ATTR3]] {
1018 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
1019 ; CHECK-NEXT:    ret float [[FNEG]]
1021   %fneg = fneg float %x
1022   ret float %fneg
1025 define float @returned_fneg_noneg(float nofpclass(ninf nsub nnorm nzero) %x) {
1026 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1027 ; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @returned_fneg_noneg
1028 ; CHECK-SAME: (float nofpclass(inf zero sub norm) [[X:%.*]]) #[[ATTR3]] {
1029 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
1030 ; CHECK-NEXT:    ret float [[FNEG]]
1032   %fneg = fneg float %x
1033   ret float %fneg
1036 define float @returned_fneg_noneg_nnan_flag(float nofpclass(ninf nsub nnorm nzero) %x) {
1037 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1038 ; CHECK-LABEL: define nofpclass(nan pinf pzero psub pnorm) float @returned_fneg_noneg_nnan_flag
1039 ; CHECK-SAME: (float nofpclass(all) [[X:%.*]]) #[[ATTR3]] {
1040 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg nnan float [[X]]
1041 ; CHECK-NEXT:    ret float [[FNEG]]
1043   %fneg = fneg nnan float %x
1044   ret float %fneg
1047 define float @returned_fneg_nonsubnnorm(float nofpclass(nsub nnorm) %x) {
1048 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1049 ; CHECK-LABEL: define nofpclass(psub pnorm) float @returned_fneg_nonsubnnorm
1050 ; CHECK-SAME: (float nofpclass(sub norm) [[X:%.*]]) #[[ATTR3]] {
1051 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
1052 ; CHECK-NEXT:    ret float [[FNEG]]
1054   %fneg = fneg float %x
1055   ret float %fneg
1058 define float @returned_fneg_nopos(float nofpclass(pinf psub pnorm pzero) %x) {
1059 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1060 ; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @returned_fneg_nopos
1061 ; CHECK-SAME: (float nofpclass(inf zero sub norm) [[X:%.*]]) #[[ATTR3]] {
1062 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
1063 ; CHECK-NEXT:    ret float [[FNEG]]
1065   %fneg = fneg float %x
1066   ret float %fneg
1069 define float @returned_fneg_nopnormpsub(float nofpclass(psub pnorm) %x) {
1070 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1071 ; CHECK-LABEL: define nofpclass(nsub nnorm) float @returned_fneg_nopnormpsub
1072 ; CHECK-SAME: (float nofpclass(sub norm) [[X:%.*]]) #[[ATTR3]] {
1073 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
1074 ; CHECK-NEXT:    ret float [[FNEG]]
1076   %fneg = fneg float %x
1077   ret float %fneg
1080 define float @returned_fneg_mixed(float nofpclass(psub nnorm nzero qnan ninf) %x) {
1081 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1082 ; CHECK-LABEL: define nofpclass(qnan pinf pzero nsub pnorm) float @returned_fneg_mixed
1083 ; CHECK-SAME: (float nofpclass(qnan inf zero sub norm) [[X:%.*]]) #[[ATTR3]] {
1084 ; CHECK-NEXT:    [[FNEG:%.*]] = fneg float [[X]]
1085 ; CHECK-NEXT:    ret float [[FNEG]]
1087   %fneg = fneg float %x
1088   ret float %fneg
1091 define float @returned_fneg_fabs(float %x) {
1092 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1093 ; TUNIT-LABEL: define nofpclass(pinf pzero psub pnorm) float @returned_fneg_fabs
1094 ; TUNIT-SAME: (float nofpclass(inf zero sub norm) [[X:%.*]]) #[[ATTR3]] {
1095 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(inf zero sub norm) float @llvm.fabs.f32(float nofpclass(inf zero sub norm) [[X]]) #[[ATTR22]]
1096 ; TUNIT-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1097 ; TUNIT-NEXT:    ret float [[FNEG_FABS]]
1099 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1100 ; CGSCC-LABEL: define nofpclass(pinf pzero psub pnorm) float @returned_fneg_fabs
1101 ; CGSCC-SAME: (float nofpclass(inf zero sub norm) [[X:%.*]]) #[[ATTR3]] {
1102 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(inf zero sub norm) float @llvm.fabs.f32(float nofpclass(inf zero sub norm) [[X]]) #[[ATTR19]]
1103 ; CGSCC-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1104 ; CGSCC-NEXT:    ret float [[FNEG_FABS]]
1106   %fabs = call float @llvm.fabs.f32(float %x)
1107   %fneg.fabs = fneg float %fabs
1108   ret float %fneg.fabs
1111 define float @returned_fneg_fabs_nosnan(float nofpclass(snan) %x) {
1112 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1113 ; TUNIT-LABEL: define nofpclass(snan pinf pzero psub pnorm) float @returned_fneg_fabs_nosnan
1114 ; TUNIT-SAME: (float nofpclass(snan inf zero sub norm) [[X:%.*]]) #[[ATTR3]] {
1115 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(snan inf zero sub norm) float @llvm.fabs.f32(float nofpclass(snan inf zero sub norm) [[X]]) #[[ATTR22]]
1116 ; TUNIT-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1117 ; TUNIT-NEXT:    ret float [[FNEG_FABS]]
1119 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1120 ; CGSCC-LABEL: define nofpclass(snan pinf pzero psub pnorm) float @returned_fneg_fabs_nosnan
1121 ; CGSCC-SAME: (float nofpclass(snan inf zero sub norm) [[X:%.*]]) #[[ATTR3]] {
1122 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(snan inf zero sub norm) float @llvm.fabs.f32(float nofpclass(snan inf zero sub norm) [[X]]) #[[ATTR19]]
1123 ; CGSCC-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1124 ; CGSCC-NEXT:    ret float [[FNEG_FABS]]
1126   %fabs = call float @llvm.fabs.f32(float %x)
1127   %fneg.fabs = fneg float %fabs
1128   ret float %fneg.fabs
1131 define float @returned_fneg_fabs_noqnan(float nofpclass(qnan) %x) {
1132 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1133 ; TUNIT-LABEL: define nofpclass(qnan pinf pzero psub pnorm) float @returned_fneg_fabs_noqnan
1134 ; TUNIT-SAME: (float nofpclass(qnan inf zero sub norm) [[X:%.*]]) #[[ATTR3]] {
1135 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(qnan inf zero sub norm) float @llvm.fabs.f32(float nofpclass(qnan inf zero sub norm) [[X]]) #[[ATTR22]]
1136 ; TUNIT-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1137 ; TUNIT-NEXT:    ret float [[FNEG_FABS]]
1139 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1140 ; CGSCC-LABEL: define nofpclass(qnan pinf pzero psub pnorm) float @returned_fneg_fabs_noqnan
1141 ; CGSCC-SAME: (float nofpclass(qnan inf zero sub norm) [[X:%.*]]) #[[ATTR3]] {
1142 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(qnan inf zero sub norm) float @llvm.fabs.f32(float nofpclass(qnan inf zero sub norm) [[X]]) #[[ATTR19]]
1143 ; CGSCC-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1144 ; CGSCC-NEXT:    ret float [[FNEG_FABS]]
1146   %fabs = call float @llvm.fabs.f32(float %x)
1147   %fneg.fabs = fneg float %fabs
1148   ret float %fneg.fabs
1151 define float @returned_fneg_fabs_nonan(float nofpclass(nan) %x) {
1152 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1153 ; TUNIT-LABEL: define nofpclass(nan pinf pzero psub pnorm) float @returned_fneg_fabs_nonan
1154 ; TUNIT-SAME: (float nofpclass(all) [[X:%.*]]) #[[ATTR3]] {
1155 ; TUNIT-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float nofpclass(all) [[X]]) #[[ATTR22]]
1156 ; TUNIT-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1157 ; TUNIT-NEXT:    ret float [[FNEG_FABS]]
1159 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1160 ; CGSCC-LABEL: define nofpclass(nan pinf pzero psub pnorm) float @returned_fneg_fabs_nonan
1161 ; CGSCC-SAME: (float nofpclass(all) [[X:%.*]]) #[[ATTR3]] {
1162 ; CGSCC-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float nofpclass(all) [[X]]) #[[ATTR19]]
1163 ; CGSCC-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1164 ; CGSCC-NEXT:    ret float [[FNEG_FABS]]
1166   %fabs = call float @llvm.fabs.f32(float %x)
1167   %fneg.fabs = fneg float %fabs
1168   ret float %fneg.fabs
1171 define float @returned_fneg_fabs_noneg(float nofpclass(ninf nsub nnorm nzero) %x) {
1172 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1173 ; TUNIT-LABEL: define nofpclass(pinf pzero psub pnorm) float @returned_fneg_fabs_noneg
1174 ; TUNIT-SAME: (float nofpclass(inf zero sub norm) [[X:%.*]]) #[[ATTR3]] {
1175 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(inf zero sub norm) float @llvm.fabs.f32(float nofpclass(inf zero sub norm) [[X]]) #[[ATTR22]]
1176 ; TUNIT-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1177 ; TUNIT-NEXT:    ret float [[FNEG_FABS]]
1179 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1180 ; CGSCC-LABEL: define nofpclass(pinf pzero psub pnorm) float @returned_fneg_fabs_noneg
1181 ; CGSCC-SAME: (float nofpclass(inf zero sub norm) [[X:%.*]]) #[[ATTR3]] {
1182 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(inf zero sub norm) float @llvm.fabs.f32(float nofpclass(inf zero sub norm) [[X]]) #[[ATTR19]]
1183 ; CGSCC-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1184 ; CGSCC-NEXT:    ret float [[FNEG_FABS]]
1186   %fabs = call float @llvm.fabs.f32(float %x)
1187   %fneg.fabs = fneg float %fabs
1188   ret float %fneg.fabs
1191 define float @returned_fneg_fabs_nopos(float nofpclass(pinf psub pnorm pzero) %x) {
1192 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1193 ; TUNIT-LABEL: define nofpclass(pinf pzero psub pnorm) float @returned_fneg_fabs_nopos
1194 ; TUNIT-SAME: (float nofpclass(inf zero sub norm) [[X:%.*]]) #[[ATTR3]] {
1195 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(inf zero sub norm) float @llvm.fabs.f32(float nofpclass(inf zero sub norm) [[X]]) #[[ATTR22]]
1196 ; TUNIT-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1197 ; TUNIT-NEXT:    ret float [[FNEG_FABS]]
1199 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1200 ; CGSCC-LABEL: define nofpclass(pinf pzero psub pnorm) float @returned_fneg_fabs_nopos
1201 ; CGSCC-SAME: (float nofpclass(inf zero sub norm) [[X:%.*]]) #[[ATTR3]] {
1202 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(inf zero sub norm) float @llvm.fabs.f32(float nofpclass(inf zero sub norm) [[X]]) #[[ATTR19]]
1203 ; CGSCC-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1204 ; CGSCC-NEXT:    ret float [[FNEG_FABS]]
1206   %fabs = call float @llvm.fabs.f32(float %x)
1207   %fneg.fabs = fneg float %fabs
1208   ret float %fneg.fabs
1211 define float @returned_fneg_fabs_mixed(float nofpclass(psub nnorm nzero qnan ninf) %x) {
1212 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1213 ; TUNIT-LABEL: define nofpclass(qnan pinf pzero psub pnorm) float @returned_fneg_fabs_mixed
1214 ; TUNIT-SAME: (float nofpclass(qnan inf zero sub norm) [[X:%.*]]) #[[ATTR3]] {
1215 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(qnan inf zero sub norm) float @llvm.fabs.f32(float nofpclass(qnan inf zero sub norm) [[X]]) #[[ATTR22]]
1216 ; TUNIT-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1217 ; TUNIT-NEXT:    ret float [[FNEG_FABS]]
1219 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1220 ; CGSCC-LABEL: define nofpclass(qnan pinf pzero psub pnorm) float @returned_fneg_fabs_mixed
1221 ; CGSCC-SAME: (float nofpclass(qnan inf zero sub norm) [[X:%.*]]) #[[ATTR3]] {
1222 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(qnan inf zero sub norm) float @llvm.fabs.f32(float nofpclass(qnan inf zero sub norm) [[X]]) #[[ATTR19]]
1223 ; CGSCC-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1224 ; CGSCC-NEXT:    ret float [[FNEG_FABS]]
1226   %fabs = call float @llvm.fabs.f32(float %x)
1227   %fneg.fabs = fneg float %fabs
1228   ret float %fneg.fabs
1231 define float @returned_fneg_fabs_ninf_flag_fabs(float %x) {
1232 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1233 ; TUNIT-LABEL: define nofpclass(inf pzero psub pnorm) float @returned_fneg_fabs_ninf_flag_fabs
1234 ; TUNIT-SAME: (float nofpclass(inf zero sub norm) [[X:%.*]]) #[[ATTR3]] {
1235 ; TUNIT-NEXT:    [[FABS:%.*]] = call ninf nofpclass(inf zero sub norm) float @llvm.fabs.f32(float nofpclass(inf zero sub norm) [[X]]) #[[ATTR22]]
1236 ; TUNIT-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1237 ; TUNIT-NEXT:    ret float [[FNEG_FABS]]
1239 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1240 ; CGSCC-LABEL: define nofpclass(inf pzero psub pnorm) float @returned_fneg_fabs_ninf_flag_fabs
1241 ; CGSCC-SAME: (float nofpclass(inf zero sub norm) [[X:%.*]]) #[[ATTR3]] {
1242 ; CGSCC-NEXT:    [[FABS:%.*]] = call ninf nofpclass(inf zero sub norm) float @llvm.fabs.f32(float nofpclass(inf zero sub norm) [[X]]) #[[ATTR19]]
1243 ; CGSCC-NEXT:    [[FNEG_FABS:%.*]] = fneg float [[FABS]]
1244 ; CGSCC-NEXT:    ret float [[FNEG_FABS]]
1246   %fabs = call ninf float @llvm.fabs.f32(float %x)
1247   %fneg.fabs = fneg float %fabs
1248   ret float %fneg.fabs
1251 define float @returned_fneg_fabs_ninf_flag_fneg(float %x) {
1252 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1253 ; TUNIT-LABEL: define nofpclass(inf pzero psub pnorm) float @returned_fneg_fabs_ninf_flag_fneg
1254 ; TUNIT-SAME: (float nofpclass(inf zero sub norm) [[X:%.*]]) #[[ATTR3]] {
1255 ; TUNIT-NEXT:    [[FABS:%.*]] = call nofpclass(inf zero sub norm) float @llvm.fabs.f32(float nofpclass(inf zero sub norm) [[X]]) #[[ATTR22]]
1256 ; TUNIT-NEXT:    [[FNEG_FABS:%.*]] = fneg ninf float [[FABS]]
1257 ; TUNIT-NEXT:    ret float [[FNEG_FABS]]
1259 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1260 ; CGSCC-LABEL: define nofpclass(inf pzero psub pnorm) float @returned_fneg_fabs_ninf_flag_fneg
1261 ; CGSCC-SAME: (float nofpclass(inf zero sub norm) [[X:%.*]]) #[[ATTR3]] {
1262 ; CGSCC-NEXT:    [[FABS:%.*]] = call nofpclass(inf zero sub norm) float @llvm.fabs.f32(float nofpclass(inf zero sub norm) [[X]]) #[[ATTR19]]
1263 ; CGSCC-NEXT:    [[FNEG_FABS:%.*]] = fneg ninf float [[FABS]]
1264 ; CGSCC-NEXT:    ret float [[FNEG_FABS]]
1266   %fabs = call float @llvm.fabs.f32(float %x)
1267   %fneg.fabs = fneg ninf float %fabs
1268   ret float %fneg.fabs
1271 define float @uitofp_i32_to_f32(i32 %arg) {
1272 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1273 ; CHECK-LABEL: define nofpclass(nan inf nzero sub nnorm) float @uitofp_i32_to_f32
1274 ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] {
1275 ; CHECK-NEXT:    [[CVT:%.*]] = uitofp i32 [[ARG]] to float
1276 ; CHECK-NEXT:    ret float [[CVT]]
1278   %cvt = uitofp i32 %arg to float
1279   ret float %cvt
1282 define float @sitofp_i32_to_f32(i32 %arg) {
1283 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1284 ; CHECK-LABEL: define nofpclass(nan inf nzero sub) float @sitofp_i32_to_f32
1285 ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] {
1286 ; CHECK-NEXT:    [[CVT:%.*]] = sitofp i32 [[ARG]] to float
1287 ; CHECK-NEXT:    ret float [[CVT]]
1289   %cvt = sitofp i32 %arg to float
1290   ret float %cvt
1293 define <2 x float> @uitofp_v2i32_to_v2f32(<2 x i32> %arg) {
1294 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1295 ; CHECK-LABEL: define nofpclass(nan inf nzero sub nnorm) <2 x float> @uitofp_v2i32_to_v2f32
1296 ; CHECK-SAME: (<2 x i32> [[ARG:%.*]]) #[[ATTR3]] {
1297 ; CHECK-NEXT:    [[CVT:%.*]] = uitofp <2 x i32> [[ARG]] to <2 x float>
1298 ; CHECK-NEXT:    ret <2 x float> [[CVT]]
1300   %cvt = uitofp <2 x i32> %arg to <2 x float>
1301   ret <2 x float> %cvt
1304 define <2 x float> @sitofp_v2i32_to_v2i32(<2 x i32> %arg) {
1305 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1306 ; CHECK-LABEL: define nofpclass(nan inf nzero sub) <2 x float> @sitofp_v2i32_to_v2i32
1307 ; CHECK-SAME: (<2 x i32> [[ARG:%.*]]) #[[ATTR3]] {
1308 ; CHECK-NEXT:    [[CVT:%.*]] = sitofp <2 x i32> [[ARG]] to <2 x float>
1309 ; CHECK-NEXT:    ret <2 x float> [[CVT]]
1311   %cvt = sitofp <2 x i32> %arg to <2 x float>
1312   ret <2 x float> %cvt
1315 define half @uitofp_i17_to_f16(i17 %arg) {
1316 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1317 ; CHECK-LABEL: define nofpclass(nan ninf nzero sub nnorm) half @uitofp_i17_to_f16
1318 ; CHECK-SAME: (i17 [[ARG:%.*]]) #[[ATTR3]] {
1319 ; CHECK-NEXT:    [[CVT:%.*]] = uitofp i17 [[ARG]] to half
1320 ; CHECK-NEXT:    ret half [[CVT]]
1322   %cvt = uitofp i17 %arg to half
1323   ret half %cvt
1326 define half @sitofp_i17_to_f16(i17 %arg) {
1327 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1328 ; CHECK-LABEL: define nofpclass(nan nzero sub) half @sitofp_i17_to_f16
1329 ; CHECK-SAME: (i17 [[ARG:%.*]]) #[[ATTR3]] {
1330 ; CHECK-NEXT:    [[CVT:%.*]] = sitofp i17 [[ARG]] to half
1331 ; CHECK-NEXT:    ret half [[CVT]]
1333   %cvt = sitofp i17 %arg to half
1334   ret half %cvt
1337 define <2 x half> @uitofp_v2i17_to_v2f16(<2 x i17> %arg) {
1338 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1339 ; CHECK-LABEL: define nofpclass(nan ninf nzero sub nnorm) <2 x half> @uitofp_v2i17_to_v2f16
1340 ; CHECK-SAME: (<2 x i17> [[ARG:%.*]]) #[[ATTR3]] {
1341 ; CHECK-NEXT:    [[CVT:%.*]] = uitofp <2 x i17> [[ARG]] to <2 x half>
1342 ; CHECK-NEXT:    ret <2 x half> [[CVT]]
1344   %cvt = uitofp <2 x i17> %arg to <2 x half>
1345   ret <2 x half> %cvt
1348 define <2 x half> @sitofp_v2i17_to_v2i17(<2 x i17> %arg) {
1349 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1350 ; CHECK-LABEL: define nofpclass(nan nzero sub) <2 x half> @sitofp_v2i17_to_v2i17
1351 ; CHECK-SAME: (<2 x i17> [[ARG:%.*]]) #[[ATTR3]] {
1352 ; CHECK-NEXT:    [[CVT:%.*]] = sitofp <2 x i17> [[ARG]] to <2 x half>
1353 ; CHECK-NEXT:    ret <2 x half> [[CVT]]
1355   %cvt = sitofp <2 x i17> %arg to <2 x half>
1356   ret <2 x half> %cvt
1359 define float @assume_intersection_not_zero_and_not_nan(float %arg) {
1360 ; CHECK-LABEL: define nofpclass(nan zero) float @assume_intersection_not_zero_and_not_nan
1361 ; CHECK-SAME: (float returned nofpclass(nan zero) [[ARG:%.*]]) {
1362 ; CHECK-NEXT:  entry:
1363 ; CHECK-NEXT:    [[IS_NOT_ZERO_OR_NAN:%.*]] = fcmp une float [[ARG]], 0.000000e+00
1364 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_NOT_ZERO_OR_NAN]]) #[[ATTR18]]
1365 ; CHECK-NEXT:    [[IS_ORD:%.*]] = fcmp ord float [[ARG]], 0.000000e+00
1366 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_ORD]]) #[[ATTR18]]
1367 ; CHECK-NEXT:    call void @extern.use(float nofpclass(nan zero) [[ARG]])
1368 ; CHECK-NEXT:    ret float [[ARG]]
1370 entry:
1371   %is.not.zero.or.nan = fcmp une float %arg, 0.0
1372   call void @llvm.assume(i1 %is.not.zero.or.nan)
1373   %is.ord = fcmp ord float %arg, 0.0
1374   call void @llvm.assume(i1 %is.ord)
1375   call void @extern.use(float %arg)
1376   ret float %arg
1379 define float @assume_intersection_class(float %arg) {
1380 ; CHECK-LABEL: define nofpclass(nan inf zero sub nnorm) float @assume_intersection_class
1381 ; CHECK-SAME: (float returned nofpclass(nan inf zero sub nnorm) [[ARG:%.*]]) {
1382 ; CHECK-NEXT:  entry:
1383 ; CHECK-NEXT:    [[POS_NORMAL_OR_POS_SUBNORMAL:%.*]] = call i1 @llvm.is.fpclass.f32(float nofpclass(nan inf zero sub nnorm) [[ARG]], i32 noundef 384) #[[ATTR20]]
1384 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[POS_NORMAL_OR_POS_SUBNORMAL]]) #[[ATTR18]]
1385 ; CHECK-NEXT:    [[IS_NORMAL:%.*]] = call i1 @llvm.is.fpclass.f32(float nofpclass(nan inf zero sub nnorm) [[ARG]], i32 noundef 264) #[[ATTR20]]
1386 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[IS_NORMAL]]) #[[ATTR18]]
1387 ; CHECK-NEXT:    call void @extern.use(float nofpclass(nan inf zero sub nnorm) [[ARG]])
1388 ; CHECK-NEXT:    ret float [[ARG]]
1390 entry:
1391   %pos.normal.or.pos.subnormal = call i1 @llvm.is.fpclass.f32(float %arg, i32 384)
1392   call void @llvm.assume(i1 %pos.normal.or.pos.subnormal)
1393   %is.normal = call i1 @llvm.is.fpclass.f32(float %arg, i32 264)
1394   call void @llvm.assume(i1 %is.normal)
1396   call void @extern.use(float %arg)
1397   ret float %arg
1400 define float @assume_intersection_none(float %arg) {
1401 ; CHECK-LABEL: define nofpclass(all) float @assume_intersection_none
1402 ; CHECK-SAME: (float returned nofpclass(all) [[ARG:%.*]]) {
1403 ; CHECK-NEXT:  entry:
1404 ; CHECK-NEXT:    [[CLASS1:%.*]] = call i1 @llvm.is.fpclass.f32(float nofpclass(all) [[ARG]], i32 noundef 682) #[[ATTR20]]
1405 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[CLASS1]]) #[[ATTR18]]
1406 ; CHECK-NEXT:    [[CLASS2:%.*]] = call i1 @llvm.is.fpclass.f32(float nofpclass(all) [[ARG]], i32 noundef 341) #[[ATTR20]]
1407 ; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[CLASS2]]) #[[ATTR18]]
1408 ; CHECK-NEXT:    call void @extern.use(float nofpclass(all) [[ARG]])
1409 ; CHECK-NEXT:    ret float [[ARG]]
1411 entry:
1412   %class1 = call i1 @llvm.is.fpclass.f32(float %arg, i32 682)
1413   call void @llvm.assume(i1 %class1)
1414   %class2 = call i1 @llvm.is.fpclass.f32(float %arg, i32 341)
1415   call void @llvm.assume(i1 %class2)
1416   call void @extern.use(float %arg)
1417   ret float %arg
1420 define float @returned_extractelement_dynamic_index(<4 x float> nofpclass(nan) %vec, i32 %idx) {
1421 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1422 ; CHECK-LABEL: define nofpclass(nan) float @returned_extractelement_dynamic_index
1423 ; CHECK-SAME: (<4 x float> nofpclass(nan) [[VEC:%.*]], i32 [[IDX:%.*]]) #[[ATTR3]] {
1424 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <4 x float> [[VEC]], i32 [[IDX]]
1425 ; CHECK-NEXT:    ret float [[EXTRACT]]
1427   %extract = extractelement <4 x float> %vec, i32 %idx
1428   ret float %extract
1431 define float @returned_extractelement_index0(<4 x float> nofpclass(nan) %vec) {
1432 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1433 ; CHECK-LABEL: define nofpclass(nan) float @returned_extractelement_index0
1434 ; CHECK-SAME: (<4 x float> nofpclass(nan) [[VEC:%.*]]) #[[ATTR3]] {
1435 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <4 x float> [[VEC]], i32 0
1436 ; CHECK-NEXT:    ret float [[EXTRACT]]
1438   %extract = extractelement <4 x float> %vec, i32 0
1439   ret float %extract
1442 define float @returned_extractelement_index_oob(<4 x float> nofpclass(nan) %vec) {
1443 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1444 ; CHECK-LABEL: define nofpclass(nan) float @returned_extractelement_index_oob
1445 ; CHECK-SAME: (<4 x float> nofpclass(nan) [[VEC:%.*]]) #[[ATTR3]] {
1446 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <4 x float> [[VEC]], i32 5
1447 ; CHECK-NEXT:    ret float [[EXTRACT]]
1449   %extract = extractelement <4 x float> %vec, i32 5
1450   ret float %extract
1453 define float @returned_extractelement_scalable(<vscale x 4 x float> nofpclass(nan) %vec) {
1454 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1455 ; CHECK-LABEL: define float @returned_extractelement_scalable
1456 ; CHECK-SAME: (<vscale x 4 x float> nofpclass(nan) [[VEC:%.*]]) #[[ATTR3]] {
1457 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <vscale x 4 x float> [[VEC]], i32 0
1458 ; CHECK-NEXT:    ret float [[EXTRACT]]
1460   %extract = extractelement <vscale x 4 x float> %vec, i32 0
1461   ret float %extract
1464 define float @returned_extractvalue([4 x float] nofpclass(nan) %array) {
1465 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1466 ; CHECK-LABEL: define nofpclass(nan) float @returned_extractvalue
1467 ; CHECK-SAME: ([4 x float] nofpclass(nan) [[ARRAY:%.*]]) #[[ATTR3]] {
1468 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractvalue [4 x float] [[ARRAY]], 0
1469 ; CHECK-NEXT:    ret float [[EXTRACT]]
1471   %extract = extractvalue [4 x float] %array, 0
1472   ret float %extract
1475 define float @return_nofpclass_freeze_nan_arg(float nofpclass(nan) %arg) {
1476 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1477 ; CHECK-LABEL: define noundef float @return_nofpclass_freeze_nan_arg
1478 ; CHECK-SAME: (float nofpclass(nan) [[ARG:%.*]]) #[[ATTR3]] {
1479 ; CHECK-NEXT:    [[FREEZE:%.*]] = freeze float [[ARG]]
1480 ; CHECK-NEXT:    ret float [[FREEZE]]
1482   %freeze = freeze float %arg
1483   ret float %freeze
1486 define float @return_nofpclass_extractelement_freeze_pinf_arg(<2 x float> nofpclass(pinf) %arg) {
1487 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1488 ; CHECK-LABEL: define noundef float @return_nofpclass_extractelement_freeze_pinf_arg
1489 ; CHECK-SAME: (<2 x float> nofpclass(pinf) [[ARG:%.*]]) #[[ATTR3]] {
1490 ; CHECK-NEXT:    [[FREEZE:%.*]] = freeze <2 x float> [[ARG]]
1491 ; CHECK-NEXT:    [[ELT:%.*]] = extractelement <2 x float> [[FREEZE]], i32 0
1492 ; CHECK-NEXT:    ret float [[ELT]]
1494   %freeze = freeze <2 x float> %arg
1495   %elt = extractelement <2 x float> %freeze, i32 0
1496   ret float %elt
1499 define <4 x float> @insertelement_constant_chain() {
1500 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1501 ; CHECK-LABEL: define nofpclass(nan ninf nzero sub) <4 x float> @insertelement_constant_chain
1502 ; CHECK-SAME: () #[[ATTR3]] {
1503 ; CHECK-NEXT:    [[INS_0:%.*]] = insertelement <4 x float> poison, float 1.000000e+00, i32 0
1504 ; CHECK-NEXT:    [[INS_1:%.*]] = insertelement <4 x float> [[INS_0]], float 0.000000e+00, i32 1
1505 ; CHECK-NEXT:    [[INS_2:%.*]] = insertelement <4 x float> [[INS_1]], float -9.000000e+00, i32 2
1506 ; CHECK-NEXT:    [[INS_3:%.*]] = insertelement <4 x float> [[INS_2]], float 0x7FF0000000000000, i32 3
1507 ; CHECK-NEXT:    ret <4 x float> [[INS_3]]
1509   %ins.0 = insertelement <4 x float> poison, float 1.0, i32 0
1510   %ins.1 = insertelement <4 x float> %ins.0, float 0.0, i32 1
1511   %ins.2 = insertelement <4 x float> %ins.1, float -9.0, i32 2
1512   %ins.3 = insertelement <4 x float> %ins.2, float 0x7FF0000000000000, i32 3
1513   ret <4 x float> %ins.3
1516 define <vscale x 4 x float> @insertelement_scalable_constant_chain() {
1517 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1518 ; CHECK-LABEL: define <vscale x 4 x float> @insertelement_scalable_constant_chain
1519 ; CHECK-SAME: () #[[ATTR3]] {
1520 ; CHECK-NEXT:    [[INS_0:%.*]] = insertelement <vscale x 4 x float> poison, float 1.000000e+00, i32 0
1521 ; CHECK-NEXT:    [[INS_1:%.*]] = insertelement <vscale x 4 x float> [[INS_0]], float 0.000000e+00, i32 1
1522 ; CHECK-NEXT:    [[INS_2:%.*]] = insertelement <vscale x 4 x float> [[INS_1]], float -9.000000e+00, i32 2
1523 ; CHECK-NEXT:    [[INS_3:%.*]] = insertelement <vscale x 4 x float> [[INS_2]], float 0x7FF0000000000000, i32 3
1524 ; CHECK-NEXT:    ret <vscale x 4 x float> [[INS_3]]
1526   %ins.0 = insertelement <vscale x 4 x float> poison, float 1.0, i32 0
1527   %ins.1 = insertelement <vscale x 4 x float> %ins.0, float 0.0, i32 1
1528   %ins.2 = insertelement <vscale x 4 x float> %ins.1, float -9.0, i32 2
1529   %ins.3 = insertelement <vscale x 4 x float> %ins.2, float 0x7FF0000000000000, i32 3
1530   ret <vscale x 4 x float> %ins.3
1533 define <4 x float> @insertelement_unknown_base(<4 x float> %arg0) {
1534 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1535 ; CHECK-LABEL: define <4 x float> @insertelement_unknown_base
1536 ; CHECK-SAME: (<4 x float> [[ARG0:%.*]]) #[[ATTR3]] {
1537 ; CHECK-NEXT:    [[INSERT:%.*]] = insertelement <4 x float> [[ARG0]], float 0.000000e+00, i32 1
1538 ; CHECK-NEXT:    ret <4 x float> [[INSERT]]
1540   %insert = insertelement <4 x float> %arg0, float 0.0, i32 1
1541   ret <4 x float> %insert
1544 define float @insertelement_extractelement_same(<4 x float> %arg0) {
1545 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1546 ; CHECK-LABEL: define nofpclass(nan inf nzero sub norm) float @insertelement_extractelement_same
1547 ; CHECK-SAME: (<4 x float> nofpclass(nan inf nzero sub norm) [[ARG0:%.*]]) #[[ATTR3]] {
1548 ; CHECK-NEXT:    [[INSERT:%.*]] = insertelement <4 x float> [[ARG0]], float 0.000000e+00, i32 1
1549 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <4 x float> [[INSERT]], i32 1
1550 ; CHECK-NEXT:    ret float [[EXTRACT]]
1552   %insert = insertelement <4 x float> %arg0, float 0.0, i32 1
1553   %extract = extractelement <4 x float> %insert, i32 1
1554   ret float %extract
1557 define float @insertelement_extractelement_different(<4 x float> nofpclass(zero) %arg0) {
1558 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1559 ; CHECK-LABEL: define nofpclass(zero) float @insertelement_extractelement_different
1560 ; CHECK-SAME: (<4 x float> nofpclass(zero) [[ARG0:%.*]]) #[[ATTR3]] {
1561 ; CHECK-NEXT:    [[INSERT:%.*]] = insertelement <4 x float> [[ARG0]], float 0.000000e+00, i32 1
1562 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <4 x float> [[INSERT]], i32 2
1563 ; CHECK-NEXT:    ret float [[EXTRACT]]
1565   %insert = insertelement <4 x float> %arg0, float 0.0, i32 1
1566   %extract = extractelement <4 x float> %insert, i32 2
1567   ret float %extract
1570 define float @insertelement_extractelement_unknown(<4 x float> nofpclass(zero) %arg0, i32 %idx) {
1571 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1572 ; CHECK-LABEL: define nofpclass(nzero) float @insertelement_extractelement_unknown
1573 ; CHECK-SAME: (<4 x float> nofpclass(zero) [[ARG0:%.*]], i32 [[IDX:%.*]]) #[[ATTR3]] {
1574 ; CHECK-NEXT:    [[INSERT:%.*]] = insertelement <4 x float> [[ARG0]], float 0.000000e+00, i32 1
1575 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <4 x float> [[INSERT]], i32 [[IDX]]
1576 ; CHECK-NEXT:    ret float [[EXTRACT]]
1578   %insert = insertelement <4 x float> %arg0, float 0.0, i32 1
1579   %extract = extractelement <4 x float> %insert, i32 %idx
1580   ret float %extract
1583 define <4 x float> @insertelement_index_oob_chain() {
1584 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1585 ; CHECK-LABEL: define <4 x float> @insertelement_index_oob_chain
1586 ; CHECK-SAME: () #[[ATTR3]] {
1587 ; CHECK-NEXT:    [[INSERT:%.*]] = insertelement <4 x float> zeroinitializer, float 0x7FF0000000000000, i32 4
1588 ; CHECK-NEXT:    ret <4 x float> [[INSERT]]
1590   %insert = insertelement <4 x float> zeroinitializer, float 0x7FF0000000000000, i32 4
1591   ret <4 x float> %insert
1594 define <2 x float> @multiple_extractelement(<4 x float> nofpclass(zero) %arg0) {
1595 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1596 ; CHECK-LABEL: define nofpclass(zero) <2 x float> @multiple_extractelement
1597 ; CHECK-SAME: (<4 x float> nofpclass(zero) [[ARG0:%.*]]) #[[ATTR3]] {
1598 ; CHECK-NEXT:    [[INSERT:%.*]] = insertelement <4 x float> [[ARG0]], float 0.000000e+00, i32 1
1599 ; CHECK-NEXT:    [[EXTRACT2:%.*]] = extractelement <4 x float> [[INSERT]], i32 2
1600 ; CHECK-NEXT:    [[EXTRACT3:%.*]] = extractelement <4 x float> [[INSERT]], i32 3
1601 ; CHECK-NEXT:    [[INS_0:%.*]] = insertelement <2 x float> poison, float [[EXTRACT3]], i32 0
1602 ; CHECK-NEXT:    [[INS_1:%.*]] = insertelement <2 x float> [[INS_0]], float [[EXTRACT2]], i32 1
1603 ; CHECK-NEXT:    ret <2 x float> [[INS_1]]
1605   %insert = insertelement <4 x float> %arg0, float 0.0, i32 1
1606   %extract2 = extractelement <4 x float> %insert, i32 2
1607   %extract3 = extractelement <4 x float> %insert, i32 3
1608   %ins.0 = insertelement <2 x float> poison, float %extract3, i32 0
1609   %ins.1 = insertelement <2 x float> %ins.0, float %extract2, i32 1
1610   ret <2 x float> %ins.1
1613 ; FIXME: Doesn't actually reach computeKnownFPClass
1614 define <4 x float> @shufflevector_constexpr() {
1615 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1616 ; CHECK-LABEL: define <4 x float> @shufflevector_constexpr
1617 ; CHECK-SAME: () #[[ATTR3]] {
1618 ; 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>
1620   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>)
1623 define <4 x float> @shufflevector_concat_disjoint(<2 x float> nofpclass(nan) %arg0, <2 x float> nofpclass(inf) %arg1) {
1624 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1625 ; CHECK-LABEL: define <4 x float> @shufflevector_concat_disjoint
1626 ; CHECK-SAME: (<2 x float> nofpclass(nan) [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] {
1627 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>
1628 ; CHECK-NEXT:    ret <4 x float> [[SHUFFLE]]
1630   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
1631   ret <4 x float> %shuffle
1634 define <4 x float> @shufflevector_concat_overlap(<2 x float> nofpclass(nan norm psub) %arg0, <2 x float> nofpclass(inf nan sub) %arg1) {
1635 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1636 ; CHECK-LABEL: define nofpclass(nan psub) <4 x float> @shufflevector_concat_overlap
1637 ; CHECK-SAME: (<2 x float> nofpclass(nan psub norm) [[ARG0:%.*]], <2 x float> nofpclass(nan inf sub) [[ARG1:%.*]]) #[[ATTR3]] {
1638 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>
1639 ; CHECK-NEXT:    ret <4 x float> [[SHUFFLE]]
1641   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
1642   ret <4 x float> %shuffle
1645 define <4 x float> @shufflevector_unknown_lhs(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) {
1646 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1647 ; CHECK-LABEL: define <4 x float> @shufflevector_unknown_lhs
1648 ; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] {
1649 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 3, i32 2, i32 1, i32 0>
1650 ; CHECK-NEXT:    ret <4 x float> [[SHUFFLE]]
1652   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
1653   ret <4 x float> %shuffle
1656 define <4 x float> @shufflevector_unknown_rhs(<2 x float> nofpclass(inf) %arg0, <2 x float> %arg1) {
1657 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1658 ; CHECK-LABEL: define <4 x float> @shufflevector_unknown_rhs
1659 ; CHECK-SAME: (<2 x float> nofpclass(inf) [[ARG0:%.*]], <2 x float> [[ARG1:%.*]]) #[[ATTR3]] {
1660 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 3, i32 2, i32 1, i32 0>
1661 ; CHECK-NEXT:    ret <4 x float> [[SHUFFLE]]
1663   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
1664   ret <4 x float> %shuffle
1667 define <4 x float> @shufflevector_unknown_all(<2 x float> %arg0, <2 x float> %arg1) {
1668 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1669 ; CHECK-LABEL: define <4 x float> @shufflevector_unknown_all
1670 ; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> [[ARG1:%.*]]) #[[ATTR3]] {
1671 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 3, i32 2, i32 1, i32 0>
1672 ; CHECK-NEXT:    ret <4 x float> [[SHUFFLE]]
1674   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
1675   ret <4 x float> %shuffle
1678 define <4 x float> @shufflevector_only_demand_lhs(<2 x float> nofpclass(inf) %arg0, <2 x float> %arg1) {
1679 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1680 ; CHECK-LABEL: define nofpclass(inf) <4 x float> @shufflevector_only_demand_lhs
1681 ; CHECK-SAME: (<2 x float> nofpclass(inf) [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] {
1682 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 0, i32 1, i32 1, i32 0>
1683 ; CHECK-NEXT:    ret <4 x float> [[SHUFFLE]]
1685   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 0, i32 1, i32 1, i32 0>
1686   ret <4 x float> %shuffle
1689 define <4 x float> @shufflevector_only_demand_rhs(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) {
1690 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1691 ; CHECK-LABEL: define nofpclass(inf) <4 x float> @shufflevector_only_demand_rhs
1692 ; CHECK-SAME: (<2 x float> nofpclass(inf) [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] {
1693 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 2, i32 3, i32 3, i32 2>
1694 ; CHECK-NEXT:    ret <4 x float> [[SHUFFLE]]
1696   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 2, i32 3, i32 3, i32 2>
1697   ret <4 x float> %shuffle
1700 define <4 x float> @shufflevector_undef_demanded(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) {
1701 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1702 ; CHECK-LABEL: define <4 x float> @shufflevector_undef_demanded
1703 ; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] {
1704 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> poison
1705 ; CHECK-NEXT:    ret <4 x float> [[SHUFFLE]]
1707   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> undef
1708   ret <4 x float> %shuffle
1711 define <4 x float> @shufflevector_zeroinit_demanded(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) {
1712 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1713 ; CHECK-LABEL: define <4 x float> @shufflevector_zeroinit_demanded
1714 ; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] {
1715 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> zeroinitializer
1716 ; CHECK-NEXT:    ret <4 x float> [[SHUFFLE]]
1718   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> zeroinitializer
1719   ret <4 x float> %shuffle
1722 define float @shufflevector_extractelt0(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) {
1723 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1724 ; CHECK-LABEL: define float @shufflevector_extractelt0
1725 ; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] {
1726 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 1, i32 3, i32 0, i32 1>
1727 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <4 x float> [[SHUFFLE]], i32 0
1728 ; CHECK-NEXT:    ret float [[EXTRACT]]
1730   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 1, i32 3, i32 0, i32 1>
1731   %extract = extractelement <4 x float> %shuffle, i32 0
1732   ret float %extract
1735 define float @shufflevector_extractelt1(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) {
1736 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1737 ; CHECK-LABEL: define nofpclass(inf) float @shufflevector_extractelt1
1738 ; CHECK-SAME: (<2 x float> nofpclass(inf) [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] {
1739 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 1, i32 3, i32 0, i32 1>
1740 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <4 x float> [[SHUFFLE]], i32 1
1741 ; CHECK-NEXT:    ret float [[EXTRACT]]
1743   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 1, i32 3, i32 0, i32 1>
1744   %extract = extractelement <4 x float> %shuffle, i32 1
1745   ret float %extract
1748 define float @shufflevector_extractelt2(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) {
1749 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1750 ; CHECK-LABEL: define float @shufflevector_extractelt2
1751 ; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] {
1752 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 1, i32 3, i32 0, i32 1>
1753 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <4 x float> [[SHUFFLE]], i32 2
1754 ; CHECK-NEXT:    ret float [[EXTRACT]]
1756   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 1, i32 3, i32 0, i32 1>
1757   %extract = extractelement <4 x float> %shuffle, i32 2
1758   ret float %extract
1761 define float @shufflevector_extractelt3(<2 x float> %arg0, <2 x float> nofpclass(inf) %arg1) {
1762 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1763 ; CHECK-LABEL: define float @shufflevector_extractelt3
1764 ; CHECK-SAME: (<2 x float> [[ARG0:%.*]], <2 x float> nofpclass(inf) [[ARG1:%.*]]) #[[ATTR3]] {
1765 ; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float> [[ARG0]], <2 x float> [[ARG1]], <4 x i32> <i32 1, i32 3, i32 0, i32 1>
1766 ; CHECK-NEXT:    [[EXTRACT:%.*]] = extractelement <4 x float> [[SHUFFLE]], i32 3
1767 ; CHECK-NEXT:    ret float [[EXTRACT]]
1769   %shuffle = shufflevector <2 x float> %arg0, <2 x float> %arg1, <4 x i32> <i32 1, i32 3, i32 0, i32 1>
1770   %extract = extractelement <4 x float> %shuffle, i32 3
1771   ret float %extract
1774 define i32 @fptosi(float nofpclass(inf nan) %arg) {
1775 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1776 ; CHECK-LABEL: define i32 @fptosi
1777 ; CHECK-SAME: (float nofpclass(nan inf) [[ARG:%.*]]) #[[ATTR3]] {
1778 ; CHECK-NEXT:    [[FPTOSI:%.*]] = fptosi float [[ARG]] to i32
1779 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[FPTOSI]], 1
1780 ; CHECK-NEXT:    ret i32 [[ADD]]
1782   %fptosi = fptosi float %arg to i32
1783   %add = add i32 %fptosi, 1
1784   ret i32 %add
1787 define float @fptrunc(double nofpclass(inf nan) %arg) {
1788 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1789 ; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @fptrunc
1790 ; CHECK-SAME: (double nofpclass(nan inf nzero nsub nnorm) [[ARG:%.*]]) #[[ATTR3]] {
1791 ; CHECK-NEXT:    [[CAST:%.*]] = fptrunc double [[ARG]] to float
1792 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[CAST]], [[CAST]]
1793 ; CHECK-NEXT:    ret float [[MUL]]
1795   %cast = fptrunc double %arg to float
1796   %mul = fmul float %cast, %cast
1797   ret float %mul
1800 define double @fpext(float nofpclass(inf nan) %arg) {
1801 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1802 ; CHECK-LABEL: define nofpclass(nan ninf nzero nsub nnorm) double @fpext
1803 ; CHECK-SAME: (float nofpclass(nan inf nzero sub nnorm) [[ARG:%.*]]) #[[ATTR3]] {
1804 ; CHECK-NEXT:    [[CAST:%.*]] = fpext float [[ARG]] to double
1805 ; CHECK-NEXT:    [[MUL:%.*]] = fmul double [[CAST]], [[CAST]]
1806 ; CHECK-NEXT:    ret double [[MUL]]
1808   %cast = fpext float %arg to double
1809   %mul = fmul double %cast, %cast
1810   ret double %mul
1813 define float @atomicrmw_fadd(ptr %ptr, float nofpclass(inf nan) %val) {
1814 ; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
1815 ; CHECK-LABEL: define float @atomicrmw_fadd
1816 ; CHECK-SAME: (ptr nocapture nofree noundef nonnull dereferenceable(4) [[PTR:%.*]], float nofpclass(nan inf) [[VAL:%.*]]) #[[ATTR6:[0-9]+]] {
1817 ; CHECK-NEXT:    [[RESULT:%.*]] = atomicrmw fadd ptr [[PTR]], float [[VAL]] seq_cst, align 4
1818 ; CHECK-NEXT:    ret float [[RESULT]]
1820   %result = atomicrmw fadd ptr %ptr, float %val seq_cst
1821   ret float %result
1824 define float @load(ptr %ptr, float nofpclass(nan inf) %val) {
1825 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)
1826 ; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @load
1827 ; CHECK-SAME: (ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[PTR:%.*]], float nofpclass(nan inf) [[VAL:%.*]]) #[[ATTR7:[0-9]+]] {
1828 ; CHECK-NEXT:    store float [[VAL]], ptr [[PTR]], align 4
1829 ; CHECK-NEXT:    [[LOAD:%.*]] = load float, ptr [[PTR]], align 4
1830 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[LOAD]], [[LOAD]]
1831 ; CHECK-NEXT:    ret float [[MUL]]
1833   store float %val, ptr %ptr
1834   %load = load float, ptr %ptr
1835   %mul = fmul float %load, %load
1836   ret float %mul
1839 define float @load_atomic(ptr %ptr, float nofpclass(nan inf) %val) {
1840 ; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
1841 ; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @load_atomic
1842 ; CHECK-SAME: (ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[PTR:%.*]], float nofpclass(nan inf) [[VAL:%.*]]) #[[ATTR6]] {
1843 ; CHECK-NEXT:    store atomic float [[VAL]], ptr [[PTR]] seq_cst, align 4
1844 ; CHECK-NEXT:    [[LOAD:%.*]] = load atomic float, ptr [[PTR]] seq_cst, align 4
1845 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[LOAD]], [[LOAD]]
1846 ; CHECK-NEXT:    ret float [[MUL]]
1848   store atomic float %val, ptr %ptr seq_cst, align 4
1849   %load = load atomic float, ptr %ptr seq_cst, align 4
1850   %mul = fmul float %load, %load
1851   ret float %mul
1854 define <8 x float> @shufflevector_shufflevector(<4 x float> nofpclass(inf nan) %arg0, <4 x float> nofpclass(inf nan zero) %arg1) {
1855 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1856 ; CHECK-LABEL: define nofpclass(nan inf) <8 x float> @shufflevector_shufflevector
1857 ; CHECK-SAME: (<4 x float> nofpclass(nan inf) [[ARG0:%.*]], <4 x float> nofpclass(nan inf zero) [[ARG1:%.*]]) #[[ATTR3]] {
1858 ; CHECK-NEXT:    [[SHUFFLE0:%.*]] = shufflevector <4 x float> [[ARG0]], <4 x float> [[ARG0]], <4 x i32> <i32 3, i32 2, i32 1, i32 0>
1859 ; CHECK-NEXT:    [[SHUFFLE1:%.*]] = shufflevector <4 x float> [[ARG1]], <4 x float> [[ARG1]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>
1860 ; 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>
1861 ; CHECK-NEXT:    ret <8 x float> [[SHUFFLE2]]
1863   %shuffle0 = shufflevector <4 x float> %arg0, <4 x float> %arg0, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
1864   %shuffle1 = shufflevector <4 x float> %arg1, <4 x float> %arg1, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
1865   %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>
1866   ret <8 x float> %shuffle2
1869 define float @constrained_sitofp(i32 %arg) strictfp {
1870 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite)
1871 ; CHECK-LABEL: define nofpclass(nan nzero sub) float @constrained_sitofp
1872 ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR8:[0-9]+]] {
1873 ; CHECK-NEXT:    [[VAL:%.*]] = call nofpclass(nan nzero sub) float @llvm.experimental.constrained.sitofp.f32.i32(i32 [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR20]]
1874 ; CHECK-NEXT:    ret float [[VAL]]
1876   %val = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %arg, metadata !"round.dynamic", metadata !"fpexcept.strict")
1877   ret float %val
1880 define float @constrained_uitofp(i32 %arg) strictfp {
1881 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite)
1882 ; CHECK-LABEL: define nofpclass(nan ninf nzero sub nnorm) float @constrained_uitofp
1883 ; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR8]] {
1884 ; 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]]
1885 ; CHECK-NEXT:    ret float [[VAL]]
1887   %val = call float @llvm.experimental.constrained.uitofp.f32.i32(i32 %arg, metadata !"round.dynamic", metadata !"fpexcept.strict")
1888   ret float %val
1891 define float @fadd_p0(float %arg0) {
1892 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1893 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_p0
1894 ; CHECK-SAME: (float nofpclass(nzero) [[ARG0:%.*]]) #[[ATTR3]] {
1895 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], 0.000000e+00
1896 ; CHECK-NEXT:    ret float [[ADD]]
1898   %add = fadd float %arg0, 0.0
1899   ret float %add
1902 define float @fadd_n0(float %arg0) {
1903 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1904 ; CHECK-LABEL: define float @fadd_n0
1905 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR3]] {
1906 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], -0.000000e+00
1907 ; CHECK-NEXT:    ret float [[ADD]]
1909   %add = fadd float %arg0, -0.0
1910   ret float %add
1913 define float @fsub_p0(float %arg0) {
1914 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1915 ; CHECK-LABEL: define float @fsub_p0
1916 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR3]] {
1917 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[ARG0]], 0.000000e+00
1918 ; CHECK-NEXT:    ret float [[SUB]]
1920   %sub = fsub float %arg0, 0.0
1921   ret float %sub
1924 define float @fsub_n0(float %arg0) {
1925 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1926 ; CHECK-LABEL: define nofpclass(nzero) float @fsub_n0
1927 ; CHECK-SAME: (float nofpclass(nzero) [[ARG0:%.*]]) #[[ATTR3]] {
1928 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[ARG0]], -0.000000e+00
1929 ; CHECK-NEXT:    ret float [[SUB]]
1931   %sub = fsub float %arg0, -0.0
1932   ret float %sub
1935 define float @fsub_p0_commute(float %arg0) {
1936 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1937 ; CHECK-LABEL: define nofpclass(nzero) float @fsub_p0_commute
1938 ; CHECK-SAME: (float nofpclass(nzero) [[ARG0:%.*]]) #[[ATTR3]] {
1939 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float 0.000000e+00, [[ARG0]]
1940 ; CHECK-NEXT:    ret float [[SUB]]
1942   %sub = fsub float 0.0, %arg0
1943   ret float %sub
1946 define float @fsub_n0_commute(float %arg0) {
1947 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1948 ; CHECK-LABEL: define float @fsub_n0_commute
1949 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR3]] {
1950 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float -0.000000e+00, [[ARG0]]
1951 ; CHECK-NEXT:    ret float [[SUB]]
1953   %sub = fsub float -0.0, %arg0
1954   ret float %sub
1957 define float @fadd_p0_ftz_daz(float %arg0) #3 {
1958 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1959 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_p0_ftz_daz
1960 ; CHECK-SAME: (float nofpclass(nzero) [[ARG0:%.*]]) #[[ATTR9:[0-9]+]] {
1961 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], 0.000000e+00
1962 ; CHECK-NEXT:    ret float [[ADD]]
1964   %add = fadd float %arg0, 0.0
1965   ret float %add
1968 define float @fadd_n0_ftz_daz(float %arg0) #0 {
1969 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1970 ; CHECK-LABEL: define float @fadd_n0_ftz_daz
1971 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR10:[0-9]+]] {
1972 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], -0.000000e+00
1973 ; CHECK-NEXT:    ret float [[ADD]]
1975   %add = fadd float %arg0, -0.0
1976   ret float %add
1979 define float @fsub_p0_ftz_daz(float %arg0) #0 {
1980 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1981 ; CHECK-LABEL: define float @fsub_p0_ftz_daz
1982 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR10]] {
1983 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[ARG0]], 0.000000e+00
1984 ; CHECK-NEXT:    ret float [[SUB]]
1986   %sub = fsub float %arg0, 0.0
1987   ret float %sub
1990 define float @fsub_n0_ftz_daz(float %arg0) #0 {
1991 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1992 ; CHECK-LABEL: define float @fsub_n0_ftz_daz
1993 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR10]] {
1994 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[ARG0]], -0.000000e+00
1995 ; CHECK-NEXT:    ret float [[SUB]]
1997   %sub = fsub float %arg0, -0.0
1998   ret float %sub
2001 define float @fsub_p0_commute_ftz_daz(float %arg0) #0 {
2002 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2003 ; CHECK-LABEL: define float @fsub_p0_commute_ftz_daz
2004 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR10]] {
2005 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float 0.000000e+00, [[ARG0]]
2006 ; CHECK-NEXT:    ret float [[SUB]]
2008   %sub = fsub float 0.0, %arg0
2009   ret float %sub
2012 define float @fsub_n0_commute_ftz_daz(float %arg0) #0 {
2013 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2014 ; CHECK-LABEL: define float @fsub_n0_commute_ftz_daz
2015 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR10]] {
2016 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float -0.000000e+00, [[ARG0]]
2017 ; CHECK-NEXT:    ret float [[SUB]]
2019   %sub = fsub float -0.0, %arg0
2020   ret float %sub
2023 define float @fadd_p0_ieee_daz(float %arg0) #2 {
2024 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2025 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_p0_ieee_daz
2026 ; CHECK-SAME: (float nofpclass(nzero) [[ARG0:%.*]]) #[[ATTR11:[0-9]+]] {
2027 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], 0.000000e+00
2028 ; CHECK-NEXT:    ret float [[ADD]]
2030   %add = fadd float %arg0, 0.0
2031   ret float %add
2034 define float @fadd_p0_dapz_ieee(float %arg0) #4 {
2035 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2036 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_p0_dapz_ieee
2037 ; CHECK-SAME: (float nofpclass(nzero) [[ARG0:%.*]]) #[[ATTR12:[0-9]+]] {
2038 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], 0.000000e+00
2039 ; CHECK-NEXT:    ret float [[ADD]]
2041   %add = fadd float %arg0, 0.0
2042   ret float %add
2045 define float @fadd_n0_ieee_daz(float %arg0) #2 {
2046 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2047 ; CHECK-LABEL: define float @fadd_n0_ieee_daz
2048 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR11]] {
2049 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], -0.000000e+00
2050 ; CHECK-NEXT:    ret float [[ADD]]
2052   %add = fadd float %arg0, -0.0
2053   ret float %add
2056 define float @fsub_p0_ieee_daz(float %arg0) #2 {
2057 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2058 ; CHECK-LABEL: define float @fsub_p0_ieee_daz
2059 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR11]] {
2060 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[ARG0]], 0.000000e+00
2061 ; CHECK-NEXT:    ret float [[SUB]]
2063   %sub = fsub float %arg0, 0.0
2064   ret float %sub
2067 define float @fsub_n0_ieee_daz(float %arg0) #2 {
2068 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2069 ; CHECK-LABEL: define nofpclass(nzero) float @fsub_n0_ieee_daz
2070 ; CHECK-SAME: (float nofpclass(nzero) [[ARG0:%.*]]) #[[ATTR11]] {
2071 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float [[ARG0]], -0.000000e+00
2072 ; CHECK-NEXT:    ret float [[SUB]]
2074   %sub = fsub float %arg0, -0.0
2075   ret float %sub
2078 define float @fsub_p0_commute_ieee_daz(float %arg0) #2 {
2079 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2080 ; CHECK-LABEL: define nofpclass(nzero) float @fsub_p0_commute_ieee_daz
2081 ; CHECK-SAME: (float nofpclass(nzero) [[ARG0:%.*]]) #[[ATTR11]] {
2082 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float 0.000000e+00, [[ARG0]]
2083 ; CHECK-NEXT:    ret float [[SUB]]
2085   %sub = fsub float 0.0, %arg0
2086   ret float %sub
2089 define float @fsub_n0_commute_ieee_daz(float %arg0) #1 {
2090 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2091 ; CHECK-LABEL: define float @fsub_n0_commute_ieee_daz
2092 ; CHECK-SAME: (float [[ARG0:%.*]]) #[[ATTR13:[0-9]+]] {
2093 ; CHECK-NEXT:    [[SUB:%.*]] = fsub float -0.000000e+00, [[ARG0]]
2094 ; CHECK-NEXT:    ret float [[SUB]]
2096   %sub = fsub float -0.0, %arg0
2097   ret float %sub
2100 define float @fadd_never_negzero_or_negsub(float nofpclass(nzero nsub) %a, float nofpclass(nzero nsub) %b) {
2101 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2102 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_negsub
2103 ; CHECK-SAME: (float nofpclass(nzero nsub) [[A:%.*]], float nofpclass(nzero nsub) [[B:%.*]]) #[[ATTR3]] {
2104 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[A]], [[B]]
2105 ; CHECK-NEXT:    ret float [[ADD]]
2107   %add = fadd float %a, %b
2108   ret float %add
2111 define float @fadd_never_negzero_or_negsub_daz(float nofpclass(nzero nsub) %a, float nofpclass(nzero nsub) %b) #2 {
2112 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2113 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_negsub_daz
2114 ; CHECK-SAME: (float nofpclass(nzero nsub) [[A:%.*]], float nofpclass(nzero nsub) [[B:%.*]]) #[[ATTR11]] {
2115 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[A]], [[B]]
2116 ; CHECK-NEXT:    ret float [[ADD]]
2118   %add = fadd float %a, %b
2119   ret float %add
2122 define float @fadd_never_negzero_or_negsub_dapz(float nofpclass(nzero nsub) %a, float nofpclass(nzero nsub) %b) #5 {
2123 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2124 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_negsub_dapz
2125 ; CHECK-SAME: (float nofpclass(nzero nsub) [[A:%.*]], float nofpclass(nzero nsub) [[B:%.*]]) #[[ATTR14:[0-9]+]] {
2126 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[A]], [[B]]
2127 ; CHECK-NEXT:    ret float [[ADD]]
2129   %add = fadd float %a, %b
2130   ret float %add
2133 define float @fadd_never_negzero_or_possub(float nofpclass(nzero psub) %a, float nofpclass(nzero psub) %b) {
2134 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2135 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_possub
2136 ; CHECK-SAME: (float nofpclass(nzero psub) [[A:%.*]], float nofpclass(nzero psub) [[B:%.*]]) #[[ATTR3]] {
2137 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[A]], [[B]]
2138 ; CHECK-NEXT:    ret float [[ADD]]
2140   %add = fadd float %a, %b
2141   ret float %add
2144 define float @fadd_never_negzero_or_possub_daz(float nofpclass(nzero psub) %a, float nofpclass(nzero psub) %b) #2 {
2145 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2146 ; CHECK-LABEL: define float @fadd_never_negzero_or_possub_daz
2147 ; CHECK-SAME: (float nofpclass(nzero psub) [[A:%.*]], float nofpclass(nzero psub) [[B:%.*]]) #[[ATTR11]] {
2148 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[A]], [[B]]
2149 ; CHECK-NEXT:    ret float [[ADD]]
2151   %add = fadd float %a, %b
2152   ret float %add
2155 define float @fadd_never_negzero_or_possub_dapz(float nofpclass(nzero psub) %a, float nofpclass(nzero psub) %b) #5 {
2156 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2157 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_possub_dapz
2158 ; CHECK-SAME: (float nofpclass(nzero psub) [[A:%.*]], float nofpclass(nzero psub) [[B:%.*]]) #[[ATTR14]] {
2159 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[A]], [[B]]
2160 ; CHECK-NEXT:    ret float [[ADD]]
2162   %add = fadd float %a, %b
2163   ret float %add
2166 define float @fadd_never_negzero_or_sub_daz(float nofpclass(nzero sub) %a, float nofpclass(nzero sub) %b) #2 {
2167 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2168 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_sub_daz
2169 ; CHECK-SAME: (float nofpclass(nzero sub) [[A:%.*]], float nofpclass(nzero sub) [[B:%.*]]) #[[ATTR11]] {
2170 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[A]], [[B]]
2171 ; CHECK-NEXT:    ret float [[ADD]]
2173   %add = fadd float %a, %b
2174   ret float %add
2177 define float @fadd_never_negzero_or_sub_dapz(float nofpclass(nzero sub) %a, float nofpclass(nzero sub) %b) #5 {
2178 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2179 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_sub_dapz
2180 ; CHECK-SAME: (float nofpclass(nzero sub) [[A:%.*]], float nofpclass(nzero sub) [[B:%.*]]) #[[ATTR14]] {
2181 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[A]], [[B]]
2182 ; CHECK-NEXT:    ret float [[ADD]]
2184   %add = fadd float %a, %b
2185   ret float %add
2188 define float @fadd_known_positive_lhs(float nofpclass(ninf nsub nnorm) %arg0, float %arg1) {
2189 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2190 ; CHECK-LABEL: define float @fadd_known_positive_lhs
2191 ; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR3]] {
2192 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2193 ; CHECK-NEXT:    ret float [[ADD]]
2195   %add = fadd float %arg0, %arg1
2196   ret float %add
2199 define float @fadd_known_positive_rhs(float %arg0, float nofpclass(ninf nsub nnorm) %arg1) {
2200 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2201 ; CHECK-LABEL: define float @fadd_known_positive_rhs
2202 ; CHECK-SAME: (float [[ARG0:%.*]], float nofpclass(ninf nsub nnorm) [[ARG1:%.*]]) #[[ATTR3]] {
2203 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2204 ; CHECK-NEXT:    ret float [[ADD]]
2206   %add = fadd float %arg0, %arg1
2207   ret float %add
2210 define float @fadd_known_positive(float nofpclass(ninf nsub nnorm) %arg0, float nofpclass(ninf nsub nnorm) %arg1) {
2211 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2212 ; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @fadd_known_positive
2213 ; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nsub nnorm) [[ARG1:%.*]]) #[[ATTR3]] {
2214 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2215 ; CHECK-NEXT:    ret float [[ADD]]
2217   %add = fadd float %arg0, %arg1
2218   ret float %add
2221 define float @fadd_known_positive_daz(float nofpclass(ninf nsub nnorm) %arg0, float nofpclass(ninf nsub nnorm) %arg1) #0 {
2222 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2223 ; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @fadd_known_positive_daz
2224 ; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nsub nnorm) [[ARG1:%.*]]) #[[ATTR10]] {
2225 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2226 ; CHECK-NEXT:    ret float [[ADD]]
2228   %add = fadd float %arg0, %arg1
2229   ret float %add
2232 define float @fadd_known_positive_nzero_lhs(float nofpclass(ninf nsub nnorm nzero) %arg0, float nofpclass(ninf nsub nnorm) %arg1) {
2233 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2234 ; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @fadd_known_positive_nzero_lhs
2235 ; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nsub nnorm) [[ARG1:%.*]]) #[[ATTR3]] {
2236 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2237 ; CHECK-NEXT:    ret float [[ADD]]
2239   %add = fadd float %arg0, %arg1
2240   ret float %add
2243 define float @fadd_known_positive_nzero_rhs(float nofpclass(ninf nsub nnorm) %arg0, float nofpclass(ninf nsub nnorm nzero) %arg1) {
2244 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2245 ; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @fadd_known_positive_nzero_rhs
2246 ; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nsub nnorm) [[ARG1:%.*]]) #[[ATTR3]] {
2247 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2248 ; CHECK-NEXT:    ret float [[ADD]]
2250   %add = fadd float %arg0, %arg1
2251   ret float %add
2254 define float @fadd_known_positive_nzero(float nofpclass(ninf nsub nnorm nzero) %arg0, float nofpclass(ninf nsub nnorm nzero) %arg1) {
2255 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2256 ; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @fadd_known_positive_nzero
2257 ; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nsub nnorm) [[ARG1:%.*]]) #[[ATTR3]] {
2258 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2259 ; CHECK-NEXT:    ret float [[ADD]]
2261   %add = fadd float %arg0, %arg1
2262   ret float %add
2265 define float @fadd_known_positive_nzero_ftz_daz(float nofpclass(ninf nsub nnorm nzero) %arg0, float nofpclass(ninf nsub nnorm nzero) %arg1) #0 {
2266 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2267 ; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @fadd_known_positive_nzero_ftz_daz
2268 ; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nsub nnorm) [[ARG1:%.*]]) #[[ATTR10]] {
2269 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2270 ; CHECK-NEXT:    ret float [[ADD]]
2272   %add = fadd float %arg0, %arg1
2273   ret float %add
2276 define float @fadd_known_positive_nzero_ftz(float nofpclass(ninf nsub nnorm nzero) %arg0, float nofpclass(ninf nsub nnorm nzero) %arg1) #1 {
2277 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2278 ; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @fadd_known_positive_nzero_ftz
2279 ; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nsub nnorm) [[ARG1:%.*]]) #[[ATTR13]] {
2280 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2281 ; CHECK-NEXT:    ret float [[ADD]]
2283   %add = fadd float %arg0, %arg1
2284   ret float %add
2287 define float @fadd_known_positive_nzero_daz(float nofpclass(ninf nsub nnorm nzero) %arg0, float nofpclass(ninf nsub nnorm nzero) %arg1) #2 {
2288 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2289 ; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @fadd_known_positive_nzero_daz
2290 ; CHECK-SAME: (float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nsub nnorm) [[ARG1:%.*]]) #[[ATTR11]] {
2291 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2292 ; CHECK-NEXT:    ret float [[ADD]]
2294   %add = fadd float %arg0, %arg1
2295   ret float %add
2298 define float @fadd_known_positive_normal(float nofpclass(ninf nnorm nzero) %arg0, float nofpclass(ninf nnorm nzero) %arg1) {
2299 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2300 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_known_positive_normal
2301 ; CHECK-SAME: (float nofpclass(ninf nzero nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nnorm) [[ARG1:%.*]]) #[[ATTR3]] {
2302 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2303 ; CHECK-NEXT:    ret float [[ADD]]
2305   %add = fadd float %arg0, %arg1
2306   ret float %add
2309 define float @fadd_known_positive_normal_daz(float nofpclass(ninf nnorm nzero) %arg0, float nofpclass(ninf nnorm nzero) %arg1) #0 {
2310 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2311 ; CHECK-LABEL: define float @fadd_known_positive_normal_daz
2312 ; CHECK-SAME: (float nofpclass(ninf nzero nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nnorm) [[ARG1:%.*]]) #[[ATTR10]] {
2313 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2314 ; CHECK-NEXT:    ret float [[ADD]]
2316   %add = fadd float %arg0, %arg1
2317   ret float %add
2320 define float @fadd_known_positive_normal_except0_daz(float nofpclass(ninf nnorm) %arg0, float nofpclass(ninf nnorm) %arg1) #0 {
2321 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2322 ; CHECK-LABEL: define float @fadd_known_positive_normal_except0_daz
2323 ; CHECK-SAME: (float nofpclass(ninf nnorm) [[ARG0:%.*]], float nofpclass(ninf nnorm) [[ARG1:%.*]]) #[[ATTR10]] {
2324 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2325 ; CHECK-NEXT:    ret float [[ADD]]
2327   %add = fadd float %arg0, %arg1
2328   ret float %add
2331 define float @fadd_known_positive_normal_dapz(float nofpclass(ninf nnorm nzero) %arg0, float nofpclass(ninf nnorm nzero) %arg1) #3 {
2332 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2333 ; CHECK-LABEL: define nofpclass(nzero) float @fadd_known_positive_normal_dapz
2334 ; CHECK-SAME: (float nofpclass(ninf nzero nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nnorm) [[ARG1:%.*]]) #[[ATTR9]] {
2335 ; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
2336 ; CHECK-NEXT:    ret float [[ADD]]
2338   %add = fadd float %arg0, %arg1
2339   ret float %add
2342 define internal float @returns_fence(float %arg) {
2343 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2344 ; TUNIT-LABEL: define internal float @returns_fence
2345 ; TUNIT-SAME: (float nofpclass(nan inf) [[ARG:%.*]]) #[[ATTR3]] {
2346 ; TUNIT-NEXT:    [[RET:%.*]] = call float @llvm.arithmetic.fence.f32(float [[ARG]]) #[[ATTR22]]
2347 ; TUNIT-NEXT:    ret float [[RET]]
2349 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2350 ; CGSCC-LABEL: define internal float @returns_fence
2351 ; CGSCC-SAME: (float nofpclass(nan inf) [[ARG:%.*]]) #[[ATTR3]] {
2352 ; CGSCC-NEXT:    [[RET:%.*]] = call float @llvm.arithmetic.fence.f32(float nofpclass(nan inf) [[ARG]]) #[[ATTR19]]
2353 ; CGSCC-NEXT:    ret float [[RET]]
2355   %ret = call float @llvm.arithmetic.fence.f32(float %arg)
2356   ret float %ret
2359 ; Check that the func0 callsite is marked with both no inf and no nan
2360 define internal float @refine_callsite_attribute(float nofpclass(inf) %arg) {
2361 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2362 ; TUNIT-LABEL: define internal float @refine_callsite_attribute
2363 ; TUNIT-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR3]] {
2364 ; TUNIT-NEXT:    [[FUNC0:%.*]] = call float @returns_fence(float nofpclass(nan inf) [[ARG]]) #[[ATTR19]]
2365 ; TUNIT-NEXT:    [[RET:%.*]] = call float @llvm.arithmetic.fence.f32(float [[FUNC0]]) #[[ATTR22]]
2366 ; TUNIT-NEXT:    ret float [[RET]]
2368 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
2369 ; CGSCC-LABEL: define internal float @refine_callsite_attribute
2370 ; CGSCC-SAME: (float nofpclass(inf) [[ARG:%.*]]) #[[ATTR4]] {
2371 ; CGSCC-NEXT:    [[FUNC0:%.*]] = call float @returns_fence(float nofpclass(nan inf) [[ARG]]) #[[ATTR19]]
2372 ; CGSCC-NEXT:    [[RET:%.*]] = call float @llvm.arithmetic.fence.f32(float [[FUNC0]]) #[[ATTR19]]
2373 ; CGSCC-NEXT:    ret float [[RET]]
2375   %func0 = call float @returns_fence(float nofpclass(nan) %arg)
2376   %ret = call float @llvm.arithmetic.fence.f32(float %func0)
2377   ret float %ret
2380 define float @user(float %arg) {
2381 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2382 ; TUNIT-LABEL: define float @user
2383 ; TUNIT-SAME: (float [[ARG:%.*]]) #[[ATTR3]] {
2384 ; TUNIT-NEXT:    [[FUNC1:%.*]] = call float @refine_callsite_attribute(float nofpclass(inf) [[ARG]]) #[[ATTR19]]
2385 ; TUNIT-NEXT:    ret float [[FUNC1]]
2387 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
2388 ; CGSCC-LABEL: define float @user
2389 ; CGSCC-SAME: (float [[ARG:%.*]]) #[[ATTR4]] {
2390 ; CGSCC-NEXT:    [[FUNC1:%.*]] = call float @refine_callsite_attribute(float nofpclass(inf) [[ARG]]) #[[ATTR19]]
2391 ; CGSCC-NEXT:    ret float [[FUNC1]]
2393   %func1 = call float @refine_callsite_attribute(float %arg)
2394   ret float %func1
2397 ; value is passed through memory
2398 define internal float @through_memory0(ptr %ptr.arg) {
2399 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2400 ; CGSCC-LABEL: define internal float @through_memory0
2401 ; CGSCC-SAME: (float [[TMP0:%.*]]) #[[ATTR3]] {
2402 ; CGSCC-NEXT:    [[PTR_ARG_PRIV:%.*]] = alloca float, align 4
2403 ; CGSCC-NEXT:    store float [[TMP0]], ptr [[PTR_ARG_PRIV]], align 4
2404 ; CGSCC-NEXT:    [[LOAD:%.*]] = load float, ptr [[PTR_ARG_PRIV]], align 4
2405 ; CGSCC-NEXT:    ret float [[LOAD]]
2407   %load = load float, ptr %ptr.arg
2408   ret float %load
2411 ; value is passed through memory and goes through an inferrable FP user
2412 define internal float @through_memory1(ptr %ptr.arg) {
2413 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2414 ; TUNIT-LABEL: define internal float @through_memory1
2415 ; TUNIT-SAME: (float [[TMP0:%.*]]) #[[ATTR3]] {
2416 ; TUNIT-NEXT:    [[PTR_ARG_PRIV:%.*]] = alloca float, align 4
2417 ; TUNIT-NEXT:    store float [[TMP0]], ptr [[PTR_ARG_PRIV]], align 4
2418 ; TUNIT-NEXT:    [[LOAD:%.*]] = load float, ptr [[PTR_ARG_PRIV]], align 4
2419 ; TUNIT-NEXT:    [[CALL:%.*]] = call float @llvm.arithmetic.fence.f32(float [[LOAD]]) #[[ATTR22]]
2420 ; TUNIT-NEXT:    ret float [[CALL]]
2422 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2423 ; CGSCC-LABEL: define internal float @through_memory1
2424 ; CGSCC-SAME: (float [[TMP0:%.*]]) #[[ATTR3]] {
2425 ; CGSCC-NEXT:    [[PTR_ARG_PRIV:%.*]] = alloca float, align 4
2426 ; CGSCC-NEXT:    store float [[TMP0]], ptr [[PTR_ARG_PRIV]], align 4
2427 ; CGSCC-NEXT:    [[LOAD:%.*]] = load float, ptr [[PTR_ARG_PRIV]], align 4
2428 ; CGSCC-NEXT:    [[CALL:%.*]] = call float @llvm.arithmetic.fence.f32(float [[LOAD]]) #[[ATTR19]]
2429 ; CGSCC-NEXT:    ret float [[CALL]]
2431   %load = load float, ptr %ptr.arg
2432   %call = call float @llvm.arithmetic.fence.f32(float %load)
2433   ret float %call
2436 ; value is passed through memory and goes through an uninferrable FP user
2437 define internal float @through_memory2(ptr %ptr.arg) {
2438 ; CHECK: Function Attrs: memory(readwrite, argmem: none)
2439 ; CHECK-LABEL: define internal float @through_memory2
2440 ; CHECK-SAME: (float [[TMP0:%.*]]) #[[ATTR15:[0-9]+]] {
2441 ; CHECK-NEXT:    [[PTR_ARG_PRIV:%.*]] = alloca float, align 4
2442 ; CHECK-NEXT:    store float [[TMP0]], ptr [[PTR_ARG_PRIV]], align 4
2443 ; CHECK-NEXT:    [[LOAD:%.*]] = load float, ptr [[PTR_ARG_PRIV]], align 4
2444 ; CHECK-NEXT:    [[CALL:%.*]] = call float @extern.f32(float [[LOAD]])
2445 ; CHECK-NEXT:    ret float [[CALL]]
2447   %load = load float, ptr %ptr.arg
2448   %call = call float @extern.f32(float %load)
2449   ret float %call
2452 define float @call_through_memory0(float nofpclass(nan) %val) {
2453 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2454 ; TUNIT-LABEL: define nofpclass(nan) float @call_through_memory0
2455 ; TUNIT-SAME: (float returned nofpclass(nan) [[VAL:%.*]]) #[[ATTR3]] {
2456 ; TUNIT-NEXT:    [[ALLOCA:%.*]] = alloca float, align 4
2457 ; TUNIT-NEXT:    store float [[VAL]], ptr [[ALLOCA]], align 4
2458 ; TUNIT-NEXT:    ret float [[VAL]]
2460 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
2461 ; CGSCC-LABEL: define float @call_through_memory0
2462 ; CGSCC-SAME: (float nofpclass(nan) [[VAL:%.*]]) #[[ATTR4]] {
2463 ; CGSCC-NEXT:    [[ALLOCA:%.*]] = alloca float, align 4
2464 ; CGSCC-NEXT:    store float [[VAL]], ptr [[ALLOCA]], align 4
2465 ; CGSCC-NEXT:    [[THROUGH_MEMORY:%.*]] = call float @through_memory0(float nofpclass(nan) [[VAL]]) #[[ATTR19]]
2466 ; CGSCC-NEXT:    ret float [[THROUGH_MEMORY]]
2468   %alloca = alloca float
2469   store float %val, ptr %alloca
2470   %through_memory = call float @through_memory0(ptr %alloca)
2471   ret float %through_memory
2474 define float @call_through_memory1(float nofpclass(nan) %val) {
2475 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2476 ; TUNIT-LABEL: define float @call_through_memory1
2477 ; TUNIT-SAME: (float nofpclass(nan) [[VAL:%.*]]) #[[ATTR3]] {
2478 ; TUNIT-NEXT:    [[ALLOCA:%.*]] = alloca float, align 4
2479 ; TUNIT-NEXT:    store float [[VAL]], ptr [[ALLOCA]], align 4
2480 ; TUNIT-NEXT:    [[TMP1:%.*]] = load float, ptr [[ALLOCA]], align 4
2481 ; TUNIT-NEXT:    [[THROUGH_MEMORY:%.*]] = call float @through_memory1(float [[TMP1]]) #[[ATTR21]]
2482 ; TUNIT-NEXT:    ret float [[THROUGH_MEMORY]]
2484 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
2485 ; CGSCC-LABEL: define float @call_through_memory1
2486 ; CGSCC-SAME: (float nofpclass(nan) [[VAL:%.*]]) #[[ATTR4]] {
2487 ; CGSCC-NEXT:    [[ALLOCA:%.*]] = alloca float, align 4
2488 ; CGSCC-NEXT:    store float [[VAL]], ptr [[ALLOCA]], align 4
2489 ; CGSCC-NEXT:    [[THROUGH_MEMORY:%.*]] = call float @through_memory1(float nofpclass(nan) [[VAL]]) #[[ATTR19]]
2490 ; CGSCC-NEXT:    ret float [[THROUGH_MEMORY]]
2492   %alloca = alloca float
2493   store float %val, ptr %alloca
2494   %through_memory = call float @through_memory1(ptr %alloca)
2495   ret float %through_memory
2498 define float @call_through_memory2(float nofpclass(nan) %val) {
2499 ; TUNIT-LABEL: define float @call_through_memory2
2500 ; TUNIT-SAME: (float nofpclass(nan) [[VAL:%.*]]) {
2501 ; TUNIT-NEXT:    [[ALLOCA:%.*]] = alloca float, align 4
2502 ; TUNIT-NEXT:    store float [[VAL]], ptr [[ALLOCA]], align 4
2503 ; TUNIT-NEXT:    [[TMP1:%.*]] = load float, ptr [[ALLOCA]], align 4
2504 ; TUNIT-NEXT:    [[THROUGH_MEMORY:%.*]] = call float @through_memory2(float [[TMP1]])
2505 ; TUNIT-NEXT:    ret float [[THROUGH_MEMORY]]
2507 ; CGSCC-LABEL: define float @call_through_memory2
2508 ; CGSCC-SAME: (float nofpclass(nan) [[VAL:%.*]]) {
2509 ; CGSCC-NEXT:    [[ALLOCA:%.*]] = alloca float, align 4
2510 ; CGSCC-NEXT:    store float [[VAL]], ptr [[ALLOCA]], align 4
2511 ; CGSCC-NEXT:    [[THROUGH_MEMORY:%.*]] = call float @through_memory2(float nofpclass(nan) [[VAL]])
2512 ; CGSCC-NEXT:    ret float [[THROUGH_MEMORY]]
2514   %alloca = alloca float
2515   store float %val, ptr %alloca
2516   %through_memory = call float @through_memory2(ptr %alloca)
2517   ret float %through_memory
2520 define amdgpu_kernel void @fast_pow_kernel(ptr addrspace(1) nocapture noundef writeonly align 4 %out, ptr addrspace(1) nocapture noundef readonly align 4 %in1, ptr addrspace(1) nocapture noundef readonly align 4 %in2)  {
2521 ; CHECK-LABEL: define amdgpu_kernel void @fast_pow_kernel
2522 ; CHECK-SAME: (ptr addrspace(1) nocapture nofree noundef writeonly align 4 [[OUT:%.*]], ptr addrspace(1) nocapture nofree noundef readonly align 4 [[IN1:%.*]], ptr addrspace(1) nocapture nofree noundef readonly align 4 [[IN2:%.*]]) {
2523 ; CHECK-NEXT:  entry:
2524 ; CHECK-NEXT:    [[CALL:%.*]] = tail call i64 @_Z13get_global_idj(i32 noundef 0)
2525 ; CHECK-NEXT:    [[SEXT:%.*]] = shl i64 [[CALL]], 32
2526 ; CHECK-NEXT:    [[IDXPROM:%.*]] = ashr exact i64 [[SEXT]], 32
2527 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr addrspace(1) [[IN1]], i64 [[IDXPROM]]
2528 ; CHECK-NEXT:    [[I:%.*]] = load float, ptr addrspace(1) [[ARRAYIDX]], align 4
2529 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds float, ptr addrspace(1) [[IN2]], i64 [[IDXPROM]]
2530 ; CHECK-NEXT:    [[I1:%.*]] = load float, ptr addrspace(1) [[ARRAYIDX2]], align 4
2531 ; 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]])
2532 ; CHECK-NEXT:    [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr addrspace(1) [[OUT]], i64 [[IDXPROM]]
2533 ; CHECK-NEXT:    store float [[CALL3]], ptr addrspace(1) [[ARRAYIDX5]], align 4
2534 ; CHECK-NEXT:    ret void
2536 entry:
2537   %call = tail call i64 @_Z13get_global_idj(i32 noundef 0)
2538   %sext = shl i64 %call, 32
2539   %idxprom = ashr exact i64 %sext, 32
2540   %arrayidx = getelementptr inbounds float, ptr addrspace(1) %in1, i64 %idxprom
2541   %i = load float, ptr addrspace(1) %arrayidx, align 4
2542   %arrayidx2 = getelementptr inbounds float, ptr addrspace(1) %in2, i64 %idxprom
2543   %i1 = load float, ptr addrspace(1) %arrayidx2, align 4
2544   %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)
2545   %arrayidx5 = getelementptr inbounds float, ptr addrspace(1) %out, i64 %idxprom
2546   store float %call3, ptr addrspace(1) %arrayidx5, align 4
2547   ret void
2550 define internal float @pow_wrapper(float %arg, float %arg1) {
2551 ; TUNIT: Function Attrs: norecurse
2552 ; TUNIT-LABEL: define internal float @pow_wrapper
2553 ; TUNIT-SAME: (float noundef nofpclass(nan inf) [[ARG:%.*]], float noundef nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR16:[0-9]+]] {
2554 ; TUNIT-NEXT:  bb:
2555 ; TUNIT-NEXT:    [[I:%.*]] = tail call float @pow_impl(float noundef nofpclass(nan inf) [[ARG]], float noundef nofpclass(nan inf) [[ARG1]])
2556 ; TUNIT-NEXT:    ret float [[I]]
2558 ; CGSCC-LABEL: define internal float @pow_wrapper
2559 ; CGSCC-SAME: (float noundef nofpclass(nan inf) [[ARG:%.*]], float noundef nofpclass(nan inf) [[ARG1:%.*]]) {
2560 ; CGSCC-NEXT:  bb:
2561 ; CGSCC-NEXT:    [[I:%.*]] = tail call float @pow_impl(float noundef nofpclass(nan inf) [[ARG]], float noundef nofpclass(nan inf) [[ARG1]])
2562 ; CGSCC-NEXT:    ret float [[I]]
2565   %i = tail call float @pow_impl(float %arg, float %arg1)
2566   ret float %i
2569 ; nofpclass(nan inf) should reach here through pow_wrapper
2570 define internal float @pow_impl(float %arg, float %arg1) {
2571 ; TUNIT: Function Attrs: norecurse
2572 ; TUNIT-LABEL: define internal float @pow_impl
2573 ; TUNIT-SAME: (float noundef nofpclass(nan inf) [[ARG:%.*]], float noundef nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR16]] {
2574 ; TUNIT-NEXT:  bb:
2575 ; TUNIT-NEXT:    [[IMPLEMENT_POW:%.*]] = call float asm "
2576 ; TUNIT-NEXT:    ret float [[IMPLEMENT_POW]]
2578 ; CGSCC: Function Attrs: norecurse
2579 ; CGSCC-LABEL: define internal float @pow_impl
2580 ; CGSCC-SAME: (float [[ARG:%.*]], float [[ARG1:%.*]]) #[[ATTR16:[0-9]+]] {
2581 ; CGSCC-NEXT:  bb:
2582 ; CGSCC-NEXT:    [[IMPLEMENT_POW:%.*]] = call float asm "
2583 ; CGSCC-NEXT:    ret float [[IMPLEMENT_POW]]
2586   %implement.pow = call float asm " ; do pow $0, $1, $2", "=v,v,v"(float %arg, float %arg1)
2587   ret float %implement.pow
2590 declare i64 @_Z13get_global_idj(i32 noundef)
2592 attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }
2593 attributes #1 = { "denormal-fp-math"="preserve-sign,ieee" }
2594 attributes #2 = { "denormal-fp-math"="ieee,preserve-sign" }
2595 attributes #3 = { "denormal-fp-math"="positive-zero,positive-zero" }
2596 attributes #4 = { "denormal-fp-math"="positive-zero,ieee" }
2597 attributes #5 = { "denormal-fp-math"="ieee,positive-zero" }