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
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
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
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
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
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
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
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>
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)>
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>
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>
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()
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]]
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
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()
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()
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)
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)
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)
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)
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)
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)
254 define float @recursive_phi(ptr %ptr) {
255 ; CHECK-LABEL: define nofpclass(nan) float @recursive_phi
256 ; CHECK-SAME: (ptr nofree [[PTR:%.*]]) {
258 ; CHECK-NEXT: [[RET:%.*]] = call nofpclass(nan) float @ret_nofpclass_nan()
259 ; CHECK-NEXT: br label [[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:%.*]]
265 ; CHECK-NEXT: ret float [[RET]]
268 %ret = call float @ret_nofpclass_nan()
272 %phi = phi float [%ret, %entry], [%phi, %loop]
273 %cond = load volatile i1, ptr %ptr
274 br i1 %cond, label %loop, label %exit
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 {
285 ; CHECK-NEXT: [[ISNAN:%.*]] = fcmp uno float [[ARG]], 0.000000e+00
286 ; CHECK-NEXT: br i1 [[ISNAN]], label [[BB0:%.*]], label [[BB1:%.*]]
288 ; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nan) float @ret_nofpclass_nan()
289 ; CHECK-NEXT: br label [[BB1]]
291 ; CHECK-NEXT: [[PHI:%.*]] = phi float [ [[CALL]], [[BB0]] ], [ [[ARG]], [[ENTRY:%.*]] ]
292 ; CHECK-NEXT: ret float [[PHI]]
295 %isnan = fcmp uno float %arg, 0.0
296 br i1 %isnan, label %bb0, label %bb1
299 %call = call float @ret_nofpclass_nan()
303 %phi = phi float [ %call, %bb0 ], [ %arg, %entry ]
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:%.*]]) {
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:%.*]]
315 ; CHECK-NEXT: call void @extern.use(float [[ARG]])
316 ; CHECK-NEXT: br label [[BB1]]
318 ; CHECK-NEXT: ret void
321 %is.not.nan = fcmp ord float %arg, 0.0
322 br i1 %is.not.nan, label %bb0, label %bb1
325 call void @extern.use(float %arg)
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:%.*]]) {
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]]
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)
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
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()
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
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)
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)
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
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)
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)
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:%.*]]) {
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]]
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)
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:%.*]]) {
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]]
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)
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:%.*]]) {
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]]
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)
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:%.*]]) {
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]]
519 call void @extern.use.f16(half %arg)
520 %not.inf = fcmp oeq half %arg, 0xH7C00
521 call void @llvm.assume(i1 %not.inf)
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:%.*]]) {
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]]
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)
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:%.*]]) {
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]]
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)
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:%.*]]) {
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]]
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)
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:%.*]]) {
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]]
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)
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:%.*]]) {
629 ; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
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]]
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]]
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)
648 call void @llvm.assume(i1 true) [ "nofpclass"(float %ret, i32 12) ]
649 call void @extern.use(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
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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>
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>
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]]
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)
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]]
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)
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]]
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)
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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")
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")
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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)
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)
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)
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
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)
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)
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
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
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]+]] {
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:%.*]]) {
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)
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]] {
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]+]] {
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" }