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