xref: /llvm-project/llvm/test/Transforms/Attributor/nofpclass-select.ll (revision d48d108bc66adb31185ee023e1eb0ccdda2065c1)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
3
4declare float @llvm.fabs.f32(float)
5declare float @llvm.copysign.f32(float, float)
6declare i1 @llvm.is.fpclass.f32(float, i32 immarg)
7
8; Arithmetic fence is to workaround an attributor bug where select
9; seems to be special cased when returned, such that
10; computeKnownFPClass is never called on it.
11
12declare float @llvm.arithmetic.fence.f32(float)
13
14define float @ret_select_nnan_flag(i1 %cond, float %arg0, float %arg1) {
15; CHECK-LABEL: define nofpclass(nan) float @ret_select_nnan_flag
16; CHECK-SAME: (i1 [[COND:%.*]], float [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR1:[0-9]+]] {
17; CHECK-NEXT:    [[SELECT:%.*]] = select nnan i1 [[COND]], float [[ARG0]], float [[ARG1]]
18; CHECK-NEXT:    ret float [[SELECT]]
19;
20  %select = select nnan i1 %cond, float %arg0, float %arg1
21  ret float %select
22}
23
24define float @ret_select_ninf_flag(i1 %cond, float %arg0, float %arg1) {
25; CHECK-LABEL: define nofpclass(inf) float @ret_select_ninf_flag
26; CHECK-SAME: (i1 [[COND:%.*]], float [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR1]] {
27; CHECK-NEXT:    [[SELECT:%.*]] = select ninf i1 [[COND]], float [[ARG0]], float [[ARG1]]
28; CHECK-NEXT:    ret float [[SELECT]]
29;
30  %select = select ninf i1 %cond, float %arg0, float %arg1
31  ret float %select
32}
33
34define float @ret_select_nnan_ninf_flag(i1 %cond, float %arg0, float %arg1) {
35; CHECK-LABEL: define nofpclass(nan inf) float @ret_select_nnan_ninf_flag
36; CHECK-SAME: (i1 [[COND:%.*]], float [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR1]] {
37; CHECK-NEXT:    [[SELECT:%.*]] = select nnan ninf i1 [[COND]], float [[ARG0]], float [[ARG1]]
38; CHECK-NEXT:    ret float [[SELECT]]
39;
40  %select = select nnan ninf i1 %cond, float %arg0, float %arg1
41  ret float %select
42}
43
44define float @ret_fence_select_nnan_flag(i1 %cond, float %arg0, float %arg1) {
45; CHECK-LABEL: define nofpclass(nan) float @ret_fence_select_nnan_flag
46; CHECK-SAME: (i1 [[COND:%.*]], float [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR1]] {
47; CHECK-NEXT:    [[SELECT:%.*]] = select nnan i1 [[COND]], float [[ARG0]], float [[ARG1]]
48; CHECK-NEXT:    [[FENCE:%.*]] = call nofpclass(nan) float @llvm.arithmetic.fence.f32(float [[SELECT]]) #[[ATTR2:[0-9]+]]
49; CHECK-NEXT:    ret float [[FENCE]]
50;
51  %select = select nnan i1 %cond, float %arg0, float %arg1
52  %fence = call float @llvm.arithmetic.fence.f32(float %select)
53  ret float %fence
54}
55
56define float @ret_select_nonan__noinf_nonan(i1 %cond, float nofpclass(nan) %arg0, float nofpclass(nan inf) %arg1) {
57; CHECK-LABEL: define nofpclass(nan) float @ret_select_nonan__noinf_nonan
58; CHECK-SAME: (i1 [[COND:%.*]], float nofpclass(nan) [[ARG0:%.*]], float nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR1]] {
59; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[ARG0]], float [[ARG1]]
60; CHECK-NEXT:    ret float [[SELECT]]
61;
62  %select = select i1 %cond, float %arg0, float %arg1
63  ret float %select
64}
65
66; Clamp nan to 0 pattern
67define float @ret_select_clamp_nan_to_zero_uno(float %arg) {
68; CHECK-LABEL: define nofpclass(nan) float @ret_select_clamp_nan_to_zero_uno
69; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
70; CHECK-NEXT:    [[IS_NAN:%.*]] = fcmp uno float [[ARG]], 0.000000e+00
71; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_NAN]], float 0.000000e+00, float [[ARG]]
72; CHECK-NEXT:    ret float [[SELECT]]
73;
74  %is.nan = fcmp uno float %arg, 0.0
75  %select = select i1 %is.nan, float 0.0, float %arg
76  ret float %select
77}
78
79define float @ret_select_clamp_nan_to_zero_ord(float %arg) {
80; CHECK-LABEL: define nofpclass(nan) float @ret_select_clamp_nan_to_zero_ord
81; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
82; CHECK-NEXT:    [[NOT_NAN:%.*]] = fcmp ord float [[ARG]], 0.000000e+00
83; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[NOT_NAN]], float [[ARG]], float 0.000000e+00
84; CHECK-NEXT:    ret float [[SELECT]]
85;
86  %not.nan = fcmp ord float %arg, 0.0
87  %select = select i1 %not.nan, float %arg, float 0.0
88  ret float %select
89}
90
91define float @ret_select_clamp_onlynans(float %arg) {
92; CHECK-LABEL: define nofpclass(inf zero sub norm) float @ret_select_clamp_onlynans
93; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
94; CHECK-NEXT:    [[NOT_NAN:%.*]] = fcmp ord float [[ARG]], 0.000000e+00
95; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[NOT_NAN]], float 0x7FF8000000000000, float [[ARG]]
96; CHECK-NEXT:    ret float [[SELECT]]
97;
98  %not.nan = fcmp ord float %arg, 0.0
99  %select = select i1 %not.nan, float 0x7FF8000000000000, float %arg
100  ret float %select
101}
102
103define float @clamp_nonfinite_to_normal_olt(float %arg) {
104; CHECK-LABEL: define nofpclass(nan inf) float @clamp_nonfinite_to_normal_olt
105; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
106; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR2]]
107; CHECK-NEXT:    [[IS_FINITE:%.*]] = fcmp olt float [[FABS]], 0x7FF0000000000000
108; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_FINITE]], float [[ARG]], float 1.024000e+03
109; CHECK-NEXT:    ret float [[SELECT]]
110;
111  %fabs = call float @llvm.fabs.f32(float %arg)
112  %is.finite = fcmp olt float %fabs, 0x7FF0000000000000
113  %select = select i1 %is.finite, float %arg, float 1024.0
114  ret float %select
115}
116
117define float @clamp_eq_inf_to_pnormal(float %arg) {
118; CHECK-LABEL: define nofpclass(inf) float @clamp_eq_inf_to_pnormal
119; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
120; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR2]]
121; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[FABS]], 0x7FF0000000000000
122; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 1.024000e+03, float [[ARG]]
123; CHECK-NEXT:    ret float [[SELECT]]
124;
125  %fabs = call float @llvm.fabs.f32(float %arg)
126  %is.inf = fcmp oeq float %fabs, 0x7FF0000000000000
127  %select = select i1 %is.inf, float 1024.0, float %arg
128  ret float %select
129}
130
131define float @clamp_eq_pinf_to_pnormal(float %arg) {
132; CHECK-LABEL: define nofpclass(pinf) float @clamp_eq_pinf_to_pnormal
133; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
134; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[ARG]], 0x7FF0000000000000
135; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 1.024000e+03, float [[ARG]]
136; CHECK-NEXT:    ret float [[SELECT]]
137;
138  %is.inf = fcmp oeq float %arg, 0x7FF0000000000000
139  %select = select i1 %is.inf, float 1024.0, float %arg
140  ret float %select
141}
142
143define float @clamp_eq_ninf_to_negnormal(float %arg) {
144; CHECK-LABEL: define nofpclass(ninf) float @clamp_eq_ninf_to_negnormal
145; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
146; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[ARG]], 0xFFF0000000000000
147; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float -1.024000e+03, float [[ARG]]
148; CHECK-NEXT:    ret float [[SELECT]]
149;
150  %is.inf = fcmp oeq float %arg, 0xFFF0000000000000
151  %select = select i1 %is.inf, float -1024.0, float %arg
152  ret float %select
153}
154
155define float @clamp_eq_inf_to_nan(float %arg) {
156; CHECK-LABEL: define nofpclass(inf) float @clamp_eq_inf_to_nan
157; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
158; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR2]]
159; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[FABS]], 0x7FF0000000000000
160; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float 0x7FF8000000000000, float [[ARG]]
161; CHECK-NEXT:    ret float [[SELECT]]
162;
163  %fabs = call float @llvm.fabs.f32(float %arg)
164  %is.inf = fcmp oeq float %fabs, 0x7FF0000000000000
165  %select = select i1 %is.inf, float 0x7FF8000000000000, float %arg
166  ret float %select
167}
168
169define float @ret_select_clamp_nan_to_zero_uno_returned_different_arg(float %arg0, float %arg1) {
170; CHECK-LABEL: define float @ret_select_clamp_nan_to_zero_uno_returned_different_arg
171; CHECK-SAME: (float [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR1]] {
172; CHECK-NEXT:    [[IS_NAN:%.*]] = fcmp uno float [[ARG0]], 0.000000e+00
173; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_NAN]], float 0.000000e+00, float [[ARG1]]
174; CHECK-NEXT:    ret float [[SELECT]]
175;
176  %is.nan = fcmp uno float %arg0, 0.0
177  %select = select i1 %is.nan, float 0.0, float %arg1
178  ret float %select
179}
180
181define float @isfinite_select_fabs_val_0(float %arg) {
182; CHECK-LABEL: define nofpclass(nan inf nzero nsub nnorm) float @isfinite_select_fabs_val_0
183; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
184; CHECK-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float [[ARG]]) #[[ATTR2]]
185; CHECK-NEXT:    [[IS_FINITE:%.*]] = fcmp olt float [[FABS]], 0x7FF0000000000000
186; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_FINITE]], float [[FABS]], float 1.024000e+03
187; CHECK-NEXT:    ret float [[SELECT]]
188;
189  %fabs = call float @llvm.fabs.f32(float %arg)
190  %is.finite = fcmp olt float %fabs, 0x7FF0000000000000
191  %select = select i1 %is.finite, float %fabs, float 1024.0
192  ret float %select
193}
194
195define float @isfinite_select_fabs_val_1(float %arg) {
196; CHECK-LABEL: define nofpclass(nan inf nzero nsub nnorm) float @isfinite_select_fabs_val_1
197; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
198; CHECK-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float [[ARG]]) #[[ATTR2]]
199; CHECK-NEXT:    [[NOT_IS_FINITE:%.*]] = fcmp uge float [[FABS]], 0x3810000000000000
200; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[NOT_IS_FINITE]], float 1.024000e+03, float [[FABS]]
201; CHECK-NEXT:    ret float [[SELECT]]
202;
203  %fabs = call float @llvm.fabs.f32(float %arg)
204  %not.is.finite = fcmp uge float %fabs, 0x3810000000000000
205  %select = select i1 %not.is.finite, float 1024.0, float %fabs
206  ret float %select
207}
208
209define float @clamp_denormal_to_poszero(float %arg) {
210; CHECK-LABEL: define nofpclass(nzero sub) float @clamp_denormal_to_poszero
211; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
212; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR2]]
213; CHECK-NEXT:    [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS]], 0x3810000000000000
214; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_DENORM_OR_ZERO]], float 0.000000e+00, float [[ARG]]
215; CHECK-NEXT:    ret float [[SELECT]]
216;
217  %fabs = call float @llvm.fabs.f32(float %arg)
218  %is.denorm.or.zero = fcmp olt float %fabs, 0x3810000000000000
219  %select = select i1 %is.denorm.or.zero, float 0.0, float %arg
220  ret float %select
221}
222
223define float @clamp_denormal_to_negzero(float %arg) {
224; CHECK-LABEL: define nofpclass(pzero sub) float @clamp_denormal_to_negzero
225; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
226; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR2]]
227; CHECK-NEXT:    [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS]], 0x3810000000000000
228; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_DENORM_OR_ZERO]], float -0.000000e+00, float [[ARG]]
229; CHECK-NEXT:    ret float [[SELECT]]
230;
231  %fabs = call float @llvm.fabs.f32(float %arg)
232  %is.denorm.or.zero = fcmp olt float %fabs, 0x3810000000000000
233  %select = select i1 %is.denorm.or.zero, float -0.0, float %arg
234  ret float %select
235}
236
237define float @clamp_denormal_to_zero_copysign(float %arg) {
238; CHECK-LABEL: define nofpclass(sub) float @clamp_denormal_to_zero_copysign
239; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
240; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR2]]
241; CHECK-NEXT:    [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS]], 0x3810000000000000
242; CHECK-NEXT:    [[ZERO:%.*]] = call float @llvm.copysign.f32(float noundef 0.000000e+00, float [[ARG]]) #[[ATTR2]]
243; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_DENORM_OR_ZERO]], float [[ZERO]], float [[ARG]]
244; CHECK-NEXT:    ret float [[SELECT]]
245;
246  %fabs = call float @llvm.fabs.f32(float %arg)
247  %is.denorm.or.zero = fcmp olt float %fabs, 0x3810000000000000
248  %zero = call float @llvm.copysign.f32(float 0.0, float %arg)
249  %select = select i1 %is.denorm.or.zero, float %zero, float %arg
250  ret float %select
251}
252
253define float @clamp_only_denormal_or_zero(float %arg) {
254; CHECK-LABEL: define nofpclass(nan inf norm) float @clamp_only_denormal_or_zero
255; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
256; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR2]]
257; CHECK-NEXT:    [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS]], 0x3810000000000000
258; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_DENORM_OR_ZERO]], float [[ARG]], float 0.000000e+00
259; CHECK-NEXT:    ret float [[SELECT]]
260;
261  %fabs = call float @llvm.fabs.f32(float %arg)
262  %is.denorm.or.zero = fcmp olt float %fabs, 0x3810000000000000
263  %select = select i1 %is.denorm.or.zero, float %arg, float 0.0
264  ret float %select
265}
266
267define float @clamp_inf_to_fabs(float %arg) {
268; CHECK-LABEL: define float @clamp_inf_to_fabs
269; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
270; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR2]]
271; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[FABS]], 0x7FF0000000000000
272; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float [[FABS]], float [[ARG]]
273; CHECK-NEXT:    ret float [[SELECT]]
274;
275  %fabs = call float @llvm.fabs.f32(float %arg)
276  %is.inf = fcmp oeq float %fabs, 0x7FF0000000000000
277  %select = select i1 %is.inf, float %fabs, float %arg
278  ret float %select
279}
280
281define float @not_clamp_inf_to_fabs(float %arg) {
282; CHECK-LABEL: define float @not_clamp_inf_to_fabs
283; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
284; CHECK-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float [[ARG]]) #[[ATTR2]]
285; CHECK-NEXT:    [[IS_INF:%.*]] = fcmp oeq float [[FABS]], 0x7FF0000000000000
286; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_INF]], float [[ARG]], float [[FABS]]
287; CHECK-NEXT:    ret float [[SELECT]]
288;
289  %fabs = call float @llvm.fabs.f32(float %arg)
290  %is.inf = fcmp oeq float %fabs, 0x7FF0000000000000
291  %select = select i1 %is.inf, float %arg, float %fabs
292  ret float %select
293}
294
295define float @clamp_zero_to_inf(float %arg) {
296; CHECK-LABEL: define nofpclass(zero) float @clamp_zero_to_inf
297; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
298; CHECK-NEXT:    [[IS_ZERO:%.*]] = fcmp oeq float [[ARG]], 0.000000e+00
299; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_ZERO]], float 0x7FF0000000000000, float [[ARG]]
300; CHECK-NEXT:    ret float [[SELECT]]
301;
302  %is.zero = fcmp oeq float %arg, 0.0
303  %select = select i1 %is.zero, float 0x7FF0000000000000, float %arg
304  ret float %select
305}
306
307define float @clamp_zero_to_only_inf(float %arg) {
308; CHECK-LABEL: define nofpclass(nan ninf sub norm) float @clamp_zero_to_only_inf
309; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
310; CHECK-NEXT:    [[IS_ZERO:%.*]] = fcmp oeq float [[ARG]], 0.000000e+00
311; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_ZERO]], float [[ARG]], float 0x7FF0000000000000
312; CHECK-NEXT:    ret float [[SELECT]]
313;
314  %is.zero = fcmp oeq float %arg, 0.0
315  %select = select i1 %is.zero, float %arg, float 0x7FF0000000000000
316  ret float %select
317}
318
319define float @clamp_is_class_subnormal_or_inf_to_nan(float %arg) {
320; CHECK-LABEL: define nofpclass(inf sub) float @clamp_is_class_subnormal_or_inf_to_nan
321; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
322; CHECK-NEXT:    [[IS_SUBNORMAL_OR_INF:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG]], i32 noundef 660) #[[ATTR2]]
323; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_SUBNORMAL_OR_INF]], float 0x7FF8000000000000, float [[ARG]]
324; CHECK-NEXT:    ret float [[SELECT]]
325;
326  %is.subnormal.or.inf = call i1 @llvm.is.fpclass.f32(float %arg, i32 660)
327  %select = select i1 %is.subnormal.or.inf, float 0x7FF8000000000000, float %arg
328  ret float %select
329}
330
331define float @clamp_is_class_subnormal_or_inf_to_nan_swap(float %arg) {
332; CHECK-LABEL: define nofpclass(inf sub) float @clamp_is_class_subnormal_or_inf_to_nan_swap
333; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
334; CHECK-NEXT:    [[NOT_IS_SUBNORMAL_OR_INF:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG]], i32 noundef 363) #[[ATTR2]]
335; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[NOT_IS_SUBNORMAL_OR_INF]], float [[ARG]], float 0x7FF8000000000000
336; CHECK-NEXT:    ret float [[SELECT]]
337;
338  %not.is.subnormal.or.inf = call i1 @llvm.is.fpclass.f32(float %arg, i32 363)
339  %select = select i1 %not.is.subnormal.or.inf, float %arg, float 0x7FF8000000000000
340  ret float %select
341}
342
343define float @ret_select_clamp_nan_to_zero_fpclass(float %arg) {
344; CHECK-LABEL: define nofpclass(nan) float @ret_select_clamp_nan_to_zero_fpclass
345; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
346; CHECK-NEXT:    [[IS_NAN:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG]], i32 noundef 3) #[[ATTR2]]
347; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_NAN]], float 0.000000e+00, float [[ARG]]
348; CHECK-NEXT:    ret float [[SELECT]]
349;
350  %is.nan = call i1 @llvm.is.fpclass.f32(float %arg, i32 3)
351  %select = select i1 %is.nan, float 0.0, float %arg
352  ret float %select
353}
354
355define float @ret_select_clamp_snan_to_zero_fpclass(float %arg) {
356; CHECK-LABEL: define nofpclass(snan) float @ret_select_clamp_snan_to_zero_fpclass
357; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
358; CHECK-NEXT:    [[IS_NAN:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG]], i32 noundef 1) #[[ATTR2]]
359; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_NAN]], float 0.000000e+00, float [[ARG]]
360; CHECK-NEXT:    ret float [[SELECT]]
361;
362  %is.nan = call i1 @llvm.is.fpclass.f32(float %arg, i32 1)
363  %select = select i1 %is.nan, float 0.0, float %arg
364  ret float %select
365}
366
367define float @ret_select_clamp_qnan_to_zero_fpclass(float %arg) {
368; CHECK-LABEL: define nofpclass(qnan) float @ret_select_clamp_qnan_to_zero_fpclass
369; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
370; CHECK-NEXT:    [[IS_NAN:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG]], i32 noundef 2) #[[ATTR2]]
371; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_NAN]], float 0.000000e+00, float [[ARG]]
372; CHECK-NEXT:    ret float [[SELECT]]
373;
374  %is.nan = call i1 @llvm.is.fpclass.f32(float %arg, i32 2)
375  %select = select i1 %is.nan, float 0.0, float %arg
376  ret float %select
377}
378
379define float @ret_select_clamp_nan_to_zero_fpclass_other_val(float %arg0, float %arg1) {
380; CHECK-LABEL: define float @ret_select_clamp_nan_to_zero_fpclass_other_val
381; CHECK-SAME: (float [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR1]] {
382; CHECK-NEXT:    [[IS_NAN:%.*]] = call i1 @llvm.is.fpclass.f32(float [[ARG0]], i32 noundef 3) #[[ATTR2]]
383; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_NAN]], float 0.000000e+00, float [[ARG1]]
384; CHECK-NEXT:    ret float [[SELECT]]
385;
386  %is.nan = call i1 @llvm.is.fpclass.f32(float %arg0, i32 3)
387  %select = select i1 %is.nan, float 0.0, float %arg1
388  ret float %select
389}
390
391define float @clamp_is_denorm_or_zero_to_fneg(float %arg) {
392; CHECK-LABEL: define float @clamp_is_denorm_or_zero_to_fneg
393; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
394; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR2]]
395; CHECK-NEXT:    [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS]], 0x3810000000000000
396; CHECK-NEXT:    [[NEG_ARG:%.*]] = fneg float [[ARG]]
397; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_DENORM_OR_ZERO]], float [[NEG_ARG]], float [[ARG]]
398; CHECK-NEXT:    ret float [[SELECT]]
399;
400  %fabs = call float @llvm.fabs.f32(float %arg)
401  %is.denorm.or.zero = fcmp olt float %fabs, 0x3810000000000000
402  %neg.arg = fneg float %arg
403  %select = select i1 %is.denorm.or.zero, float %neg.arg, float %arg
404  ret float %select
405}
406
407define float @select_is_denorm_or_zero_to_fneg_or_fabs(float %arg) {
408; CHECK-LABEL: define float @select_is_denorm_or_zero_to_fneg_or_fabs
409; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
410; CHECK-NEXT:    [[FABS:%.*]] = call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float [[ARG]]) #[[ATTR2]]
411; CHECK-NEXT:    [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS]], 0x3810000000000000
412; CHECK-NEXT:    [[NEG_ARG:%.*]] = fneg float [[ARG]]
413; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_DENORM_OR_ZERO]], float [[NEG_ARG]], float [[FABS]]
414; CHECK-NEXT:    ret float [[SELECT]]
415;
416  %fabs = call float @llvm.fabs.f32(float %arg)
417  %is.denorm.or.zero = fcmp olt float %fabs, 0x3810000000000000
418  %neg.arg = fneg float %arg
419  %select = select i1 %is.denorm.or.zero, float %neg.arg, float %fabs
420  ret float %select
421}
422
423define float @select_is_denorm_or_zero_to_fabs_or_fneg(float %arg) {
424; CHECK-LABEL: define float @select_is_denorm_or_zero_to_fabs_or_fneg
425; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
426; CHECK-NEXT:    [[FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR2]]
427; CHECK-NEXT:    [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS]], 0x3810000000000000
428; CHECK-NEXT:    [[NEG_ARG:%.*]] = fneg float [[ARG]]
429; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[IS_DENORM_OR_ZERO]], float [[FABS]], float [[NEG_ARG]]
430; CHECK-NEXT:    ret float [[SELECT]]
431;
432  %fabs = call float @llvm.fabs.f32(float %arg)
433  %is.denorm.or.zero = fcmp olt float %fabs, 0x3810000000000000
434  %neg.arg = fneg float %arg
435  %select = select i1 %is.denorm.or.zero, float %fabs, float %neg.arg
436  ret float %select
437}
438
439;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
440; TUNIT: {{.*}}
441