1341 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 22; RUN: opt -S -passes=instcombine < %s | FileCheck %s3 4declare float @llvm.fabs.f32(float)5declare float @llvm.copysign.f32(float, float)6declare void @llvm.assume(i1 noundef)7declare float @llvm.log2.f32(float)8declare float @llvm.exp2.f32(float)9declare float @llvm.trunc.f32(float)10declare float @llvm.arithmetic.fence.f32(float)11declare float @llvm.minnum.f32(float, float)12declare float @llvm.maxnum.f32(float, float)13 14 15define float @ninf_user_select_inf(i1 %cond, float %x, float %y) {16; CHECK-LABEL: define float @ninf_user_select_inf17; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], float [[Y:%.*]]) {18; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[X]], float 0x7FF000000000000019; CHECK-NEXT: [[NINF_USER:%.*]] = fmul ninf float [[Y]], [[SELECT]]20; CHECK-NEXT: ret float [[NINF_USER]]21;22 %select = select i1 %cond, float %x, float 0x7FF000000000000023 %ninf.user = fmul ninf float %y, %select24 ret float %ninf.user25}26 27define nofpclass(inf) float @ret_nofpclass_inf_poison() {28; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf_poison() {29; CHECK-NEXT: ret float poison30;31 ret float poison32}33 34define nofpclass(inf) float @ret_nofpclass_inf_undef() {35; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf_undef() {36; CHECK-NEXT: ret float undef37;38 ret float undef39}40 41; Make sure there's no infinite loop42define nofpclass(all) float @ret_nofpclass_all_var(float %arg) {43; CHECK-LABEL: define nofpclass(all) float @ret_nofpclass_all_var44; CHECK-SAME: (float [[ARG:%.*]]) {45; CHECK-NEXT: ret float poison46;47 ret float %arg48}49 50; Make sure there's no infinite loop51define nofpclass(all) <2 x float> @ret_nofpclass_all_var_vector(<2 x float> %arg) {52; CHECK-LABEL: define nofpclass(all) <2 x float> @ret_nofpclass_all_var_vector53; CHECK-SAME: (<2 x float> [[ARG:%.*]]) {54; CHECK-NEXT: ret <2 x float> poison55;56 ret <2 x float> %arg57}58 59define nofpclass(inf) float @ret_nofpclass_inf__0() {60; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__0() {61; CHECK-NEXT: ret float 0.000000e+0062;63 ret float 0.064}65 66define nofpclass(inf) float @ret_nofpclass_inf__pinf() {67; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__pinf() {68; CHECK-NEXT: ret float poison69;70 ret float 0x7FF000000000000071}72 73define nofpclass(pinf) float @ret_nofpclass_pinf__pinf() {74; CHECK-LABEL: define nofpclass(pinf) float @ret_nofpclass_pinf__pinf() {75; CHECK-NEXT: ret float poison76;77 ret float 0x7FF000000000000078}79 80define nofpclass(pinf) float @ret_nofpclass_pinf__ninf() {81; CHECK-LABEL: define nofpclass(pinf) float @ret_nofpclass_pinf__ninf() {82; CHECK-NEXT: ret float 0xFFF000000000000083;84 ret float 0xFFF000000000000085}86 87define nofpclass(inf) float @ret_nofpclass_inf__ninf() {88; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__ninf() {89; CHECK-NEXT: ret float poison90;91 ret float 0xFFF000000000000092}93 94; Basic aggregate tests to ensure this does not crash.95define nofpclass(nan) { float } @ret_nofpclass_struct_ty() {96; CHECK-LABEL: define nofpclass(nan) { float } @ret_nofpclass_struct_ty() {97; CHECK-NEXT: entry:98; CHECK-NEXT: ret { float } zeroinitializer99;100entry:101 ret { float } zeroinitializer102}103 104define nofpclass(nan) { float, float } @ret_nofpclass_multiple_elems_struct_ty() {105; CHECK-LABEL: define nofpclass(nan) { float, float } @ret_nofpclass_multiple_elems_struct_ty() {106; CHECK-NEXT: entry:107; CHECK-NEXT: ret { float, float } zeroinitializer108;109entry:110 ret { float, float } zeroinitializer111}112 113define nofpclass(nan) { <4 x float>, <4 x float> } @ret_nofpclass_vector_elems_struct_ty() {114; CHECK-LABEL: define nofpclass(nan) { <4 x float>, <4 x float> } @ret_nofpclass_vector_elems_struct_ty() {115; CHECK-NEXT: entry:116; CHECK-NEXT: ret { <4 x float>, <4 x float> } zeroinitializer117;118entry:119 ret { <4 x float>, <4 x float> } zeroinitializer120}121 122define nofpclass(nan) [ 5 x float ] @ret_nofpclass_array_ty() {123; CHECK-LABEL: define nofpclass(nan) [5 x float] @ret_nofpclass_array_ty() {124; CHECK-NEXT: entry:125; CHECK-NEXT: ret [5 x float] zeroinitializer126;127entry:128 ret [ 5 x float ] zeroinitializer129}130 131define nofpclass(nan) [ 2 x [ 5 x float ]] @ret_nofpclass_nested_array_ty() {132; CHECK-LABEL: define nofpclass(nan) [2 x [5 x float]] @ret_nofpclass_nested_array_ty() {133; CHECK-NEXT: entry:134; CHECK-NEXT: ret [2 x [5 x float]] zeroinitializer135;136entry:137 ret [ 2 x [ 5 x float ]] zeroinitializer138}139 140define nofpclass(pinf) { float } @ret_nofpclass_struct_ty_pinf__ninf() {141; CHECK-LABEL: define nofpclass(pinf) { float } @ret_nofpclass_struct_ty_pinf__ninf() {142; CHECK-NEXT: entry:143; CHECK-NEXT: ret { float } { float 0xFFF0000000000000 }144;145entry:146 ret { float } { float 0xFFF0000000000000 }147}148 149define nofpclass(pinf) { float, float } @ret_nofpclass_multiple_elems_struct_ty_pinf__ninf() {150; CHECK-LABEL: define nofpclass(pinf) { float, float } @ret_nofpclass_multiple_elems_struct_ty_pinf__ninf() {151; CHECK-NEXT: entry:152; CHECK-NEXT: ret { float, float } { float 0xFFF0000000000000, float 0xFFF0000000000000 }153;154entry:155 ret { float, float } { float 0xFFF0000000000000, float 0xFFF0000000000000 }156}157 158define nofpclass(pinf) { <2 x float> } @ret_nofpclass_vector_elems_struct_ty_pinf__ninf() {159; CHECK-LABEL: define nofpclass(pinf) { <2 x float> } @ret_nofpclass_vector_elems_struct_ty_pinf__ninf() {160; CHECK-NEXT: entry:161; CHECK-NEXT: ret { <2 x float> } { <2 x float> splat (float 0xFFF0000000000000) }162;163entry:164 ret { <2 x float>} { <2 x float> <float 0xFFF0000000000000, float 0xFFF0000000000000> }165}166 167; UTC_ARGS: --disable168; FileCheck does not like the nested square brackets.169define nofpclass(pinf) [ 1 x [ 1 x float ]] @ret_nofpclass_nested_array_ty_pinf__ninf() {170; CHECK-LABEL: @ret_nofpclass_nested_array_ty_pinf__ninf() {171; CHECK-NEXT: entry:172; CHECK-NEXT: ret {{.*}}float 0xFFF0000000000000173;174entry:175 ret [ 1 x [ 1 x float ]] [[ 1 x float ] [float 0xFFF0000000000000]]176}177; UTC_ARGS: --enable178 179define nofpclass(pzero) { float, float } @ret_nofpclass_multiple_elems_struct_ty_pzero__nzero() {180; CHECK-LABEL: define nofpclass(pzero) { float, float } @ret_nofpclass_multiple_elems_struct_ty_pzero__nzero() {181; CHECK-NEXT: entry:182; CHECK-NEXT: ret { float, float } { float -0.000000e+00, float -0.000000e+00 }183;184entry:185 ret { float, float } { float -0.0, float -0.0 }186}187 188define nofpclass(ninf) { float, float } @ret_nofpclass_multiple_elems_struct_ty_ninf__npinf() {189; CHECK-LABEL: define nofpclass(ninf) { float, float } @ret_nofpclass_multiple_elems_struct_ty_ninf__npinf() {190; CHECK-NEXT: entry:191; CHECK-NEXT: ret { float, float } { float 0x7FF0000000000000, float 0x7FF0000000000000 }192;193entry:194 ret { float, float } { float 0x7FF0000000000000, float 0x7FF0000000000000 }195}196 197; FIXME (should be poison): Support computeKnownFPClass() for non-zero aggregates.198define nofpclass(inf) { float, float } @ret_nofpclass_multiple_elems_struct_ty_inf__npinf() {199; CHECK-LABEL: define nofpclass(inf) { float, float } @ret_nofpclass_multiple_elems_struct_ty_inf__npinf() {200; CHECK-NEXT: entry:201; CHECK-NEXT: ret { float, float } { float 0x7FF0000000000000, float 0x7FF0000000000000 }202;203entry:204 ret { float, float } { float 0x7FF0000000000000, float 0x7FF0000000000000 }205}206 207; FIXME (should be poison): Support computeKnownFPClass() for non-zero aggregates.208define nofpclass(nzero) [ 1 x float ] @ret_nofpclass_multiple_elems_struct_ty_nzero_nzero() {209; CHECK-LABEL: define nofpclass(nzero) [1 x float] @ret_nofpclass_multiple_elems_struct_ty_nzero_nzero() {210; CHECK-NEXT: entry:211; CHECK-NEXT: ret [1 x float] [float -0.000000e+00]212;213entry:214 ret [ 1 x float ] [ float -0.0 ]215}216 217; Negative test, do nothing218define nofpclass(inf) float @ret_nofpclass_inf__select_nofpclass_inf_lhs(i1 %cond, float nofpclass(inf) %x, float %y) {219; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__select_nofpclass_inf_lhs220; CHECK-SAME: (i1 [[COND:%.*]], float nofpclass(inf) [[X:%.*]], float [[Y:%.*]]) {221; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[X]], float [[Y]]222; CHECK-NEXT: ret float [[SELECT]]223;224 %select = select i1 %cond, float %x, float %y225 ret float %select226}227 228; Make sure nofpclass from source argument is used, fold to %y229define nofpclass(inf) float @ret_nofpclass_inf__select_nofpclass_arg_only_inf_lhs(i1 %cond, float nofpclass(nan norm zero sub) %x, float %y) {230; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__select_nofpclass_arg_only_inf_lhs231; CHECK-SAME: (i1 [[COND:%.*]], float nofpclass(nan zero sub norm) [[X:%.*]], float [[Y:%.*]]) {232; CHECK-NEXT: ret float [[Y]]233;234 %select = select i1 %cond, float %x, float %y235 ret float %select236}237 238; Make sure nofpclass from source argument is used, fold to %x239define nofpclass(inf) float @ret_nofpclass_inf__select_nofpclass_arg_only_inf_rhs(i1 %cond, float %x, float nofpclass(nan norm zero sub) %y) {240; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__select_nofpclass_arg_only_inf_rhs241; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], float nofpclass(nan zero sub norm) [[Y:%.*]]) {242; CHECK-NEXT: ret float [[X]]243;244 %select = select i1 %cond, float %x, float %y245 ret float %select246}247 248; Fold to ret %y249define nofpclass(inf) [3 x [2 x float]] @ret_float_array(i1 %cond, [3 x [2 x float]] nofpclass(nan norm zero sub) %x, [3 x [2 x float]] %y) {250; CHECK-LABEL: define nofpclass(inf) [3 x [2 x float]] @ret_float_array251; CHECK-SAME: (i1 [[COND:%.*]], [3 x [2 x float]] nofpclass(nan zero sub norm) [[X:%.*]], [3 x [2 x float]] [[Y:%.*]]) {252; CHECK-NEXT: ret [3 x [2 x float]] [[Y]]253;254 %select = select i1 %cond, [3 x [2 x float]] %x, [3 x [2 x float]] %y255 ret [3 x [2 x float ]] %select256}257 258; Fold to ret %x259define nofpclass(inf) float @ret_nofpclass_inf__select_pinf_lhs(i1 %cond, float %x) {260; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__select_pinf_lhs261; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {262; CHECK-NEXT: ret float [[X]]263;264 %select = select i1 %cond, float 0x7FF0000000000000, float %x265 ret float %select266}267 268; Fold to ret %x269define nofpclass(inf) float @ret_nofpclass_inf__select_pinf_rhs(i1 %cond, float %x) {270; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__select_pinf_rhs271; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {272; CHECK-NEXT: ret float [[X]]273;274 %select = select i1 %cond, float %x, float 0x7FF0000000000000275 ret float %select276}277 278; Fold to poison279define nofpclass(inf) float @ret_nofpclass_inf__select_pinf_or_ninf(i1 %cond, float %x) {280; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__select_pinf_or_ninf281; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {282; CHECK-NEXT: ret float poison283;284 %select = select i1 %cond, float 0x7FF0000000000000, float 0xFFF0000000000000285 ret float %select286}287 288; Fold to poison289define nofpclass(inf) float @ret_nofpclass_inf__select_ninf_or_pinf(i1 %cond, float %x) {290; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__select_ninf_or_pinf291; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {292; CHECK-NEXT: ret float poison293;294 %select = select i1 %cond, float 0xFFF0000000000000, float 0x7FF0000000000000295 ret float %select296}297 298; Fold to pos inf299define nofpclass(ninf) float @ret_nofpclass_ninf__select_ninf_or_pinf(i1 %cond, float %x) {300; CHECK-LABEL: define nofpclass(ninf) float @ret_nofpclass_ninf__select_ninf_or_pinf301; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {302; CHECK-NEXT: ret float 0x7FF0000000000000303;304 %select = select i1 %cond, float 0xFFF0000000000000, float 0x7FF0000000000000305 ret float %select306}307 308; Fold to neg inf309define nofpclass(pinf) float @ret_nofpclass_pinf__select_ninf_or_pinf(i1 %cond, float %x) {310; CHECK-LABEL: define nofpclass(pinf) float @ret_nofpclass_pinf__select_ninf_or_pinf311; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {312; CHECK-NEXT: ret float 0xFFF0000000000000313;314 %select = select i1 %cond, float 0xFFF0000000000000, float 0x7FF0000000000000315 ret float %select316}317 318; Fold to poison319define nofpclass(zero) float @ret_nofpclass_zero__select_pzero_or_nzero(i1 %cond, float %x) {320; CHECK-LABEL: define nofpclass(zero) float @ret_nofpclass_zero__select_pzero_or_nzero321; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {322; CHECK-NEXT: ret float poison323;324 %select = select i1 %cond, float 0.0, float -0.0325 ret float %select326}327 328; Fold to +0329define nofpclass(nzero) float @ret_nofpclass_nzero__select_pzero_or_nzero(i1 %cond, float %x) {330; CHECK-LABEL: define nofpclass(nzero) float @ret_nofpclass_nzero__select_pzero_or_nzero331; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {332; CHECK-NEXT: ret float 0.000000e+00333;334 %select = select i1 %cond, float 0.0, float -0.0335 ret float %select336}337 338; Fold to -0339define nofpclass(pzero) float @ret_nofpclass_pzero__select_pzero_or_nzero(i1 %cond, float %x) {340; CHECK-LABEL: define nofpclass(pzero) float @ret_nofpclass_pzero__select_pzero_or_nzero341; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {342; CHECK-NEXT: ret float -0.000000e+00343;344 %select = select i1 %cond, float 0.0, float -0.0345 ret float %select346}347 348; Fold to ret %x349define nofpclass(inf) <2 x float> @ret_nofpclass_inf__select_pinf_lhs_vector(<2 x i1> %cond, <2 x float> %x) {350; CHECK-LABEL: define nofpclass(inf) <2 x float> @ret_nofpclass_inf__select_pinf_lhs_vector351; CHECK-SAME: (<2 x i1> [[COND:%.*]], <2 x float> [[X:%.*]]) {352; CHECK-NEXT: ret <2 x float> [[X]]353;354 %select = select <2 x i1> %cond, <2 x float> <float 0x7FF0000000000000, float 0x7FF0000000000000>, <2 x float> %x355 ret <2 x float> %select356}357 358; Fold to ret %x359define nofpclass(inf) <2 x float> @ret_nofpclass_inf__select_pinf_lhs_vector_undef(<2 x i1> %cond, <2 x float> %x) {360; CHECK-LABEL: define nofpclass(inf) <2 x float> @ret_nofpclass_inf__select_pinf_lhs_vector_undef361; CHECK-SAME: (<2 x i1> [[COND:%.*]], <2 x float> [[X:%.*]]) {362; CHECK-NEXT: ret <2 x float> [[X]]363;364 %select = select <2 x i1> %cond, <2 x float> <float 0x7FF0000000000000, float poison>, <2 x float> %x365 ret <2 x float> %select366}367 368; Fold to ret %x369define nofpclass(inf) <2 x float> @ret_nofpclass_inf__select_mixed_inf_lhs_vector(<2 x i1> %cond, <2 x float> %x) {370; CHECK-LABEL: define nofpclass(inf) <2 x float> @ret_nofpclass_inf__select_mixed_inf_lhs_vector371; CHECK-SAME: (<2 x i1> [[COND:%.*]], <2 x float> [[X:%.*]]) {372; CHECK-NEXT: ret <2 x float> [[X]]373;374 %select = select <2 x i1> %cond, <2 x float> <float 0x7FF0000000000000, float 0xFFF0000000000000>, <2 x float> %x375 ret <2 x float> %select376}377 378; Can't delete the select379define nofpclass(inf) float @ret_nofpclass_inf__select_multi_use_pinf_lhs(i1 %cond, float %x, ptr %ptr) {380; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__select_multi_use_pinf_lhs381; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], ptr [[PTR:%.*]]) {382; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float 0x7FF0000000000000, float [[X]]383; CHECK-NEXT: store float [[SELECT]], ptr [[PTR]], align 4384; CHECK-NEXT: ret float [[SELECT]]385;386 %select = select i1 %cond, float 0x7FF0000000000000, float %x387 store float %select, ptr %ptr388 ret float %select389}390 391; Can't do anything392define nofpclass(inf) float @ret_nofpclass_inf__select_p0_lhs(i1 %cond, float %x) {393; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__select_p0_lhs394; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {395; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float 0.000000e+00, float [[X]]396; CHECK-NEXT: ret float [[SELECT]]397;398 %select = select i1 %cond, float 0.0, float %x399 ret float %select400}401 402; Can't do anything403define nofpclass(inf) float @ret_nofpclass_inf__select_p0_rhs(i1 %cond, float %x) {404; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__select_p0_rhs405; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {406; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[X]], float 0.000000e+00407; CHECK-NEXT: ret float [[SELECT]]408;409 %select = select i1 %cond, float %x, float 0.0410 ret float %select411}412 413; Can't do anything414define nofpclass(nan) float @ret_nofpclass_nan__select_pinf_lhs(i1 %cond, float %x) {415; CHECK-LABEL: define nofpclass(nan) float @ret_nofpclass_nan__select_pinf_lhs416; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {417; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float 0x7FF0000000000000, float [[X]]418; CHECK-NEXT: ret float [[SELECT]]419;420 %select = select i1 %cond, float 0x7FF0000000000000, float %x421 ret float %select422}423 424; Can't do anything425define nofpclass(nan) float @ret_nofpclass_nan__select_pinf_rhs(i1 %cond, float %x) {426; CHECK-LABEL: define nofpclass(nan) float @ret_nofpclass_nan__select_pinf_rhs427; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {428; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[X]], float 0x7FF0000000000000429; CHECK-NEXT: ret float [[SELECT]]430;431 %select = select i1 %cond, float %x, float 0x7FF0000000000000432 ret float %select433}434 435define nofpclass(inf nan) float @ret_nofpclass_inf_nan__select_chain_inf_nan_0(i1 %cond, float %x) {436; CHECK-LABEL: define nofpclass(nan inf) float @ret_nofpclass_inf_nan__select_chain_inf_nan_0437; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {438; CHECK-NEXT: ret float [[X]]439;440 %select0 = select i1 %cond, float 0x7FF8000000000000, float %x441 %select1 = select i1 %cond, float 0x7FF0000000000000, float %select0442 ret float %select1443}444 445define nofpclass(inf nan) float @ret_nofpclass_inf_nan__select_chain_inf_nan_1(i1 %cond, float %x) {446; CHECK-LABEL: define nofpclass(nan inf) float @ret_nofpclass_inf_nan__select_chain_inf_nan_1447; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {448; CHECK-NEXT: ret float poison449;450 %select0 = select i1 %cond, float %x, float 0x7FF8000000000000451 %select1 = select i1 %cond, float 0x7FF0000000000000, float %select0452 ret float %select1453}454 455define nofpclass(nan) float @ret_nofpclass_nan__select_chain_inf_nan(i1 %cond, float %x) {456; CHECK-LABEL: define nofpclass(nan) float @ret_nofpclass_nan__select_chain_inf_nan457; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {458; CHECK-NEXT: [[SELECT1:%.*]] = select i1 [[COND]], float 0x7FF0000000000000, float [[X]]459; CHECK-NEXT: ret float [[SELECT1]]460;461 %select0 = select i1 %cond, float 0x7FF8000000000000, float %x462 %select1 = select i1 %cond, float 0x7FF0000000000000, float %select0463 ret float %select1464}465 466define nofpclass(inf) float @ret_nofpclass_inf__select_chain_inf_nan_0(i1 %cond, float %x) {467; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__select_chain_inf_nan_0468; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {469; CHECK-NEXT: ret float [[X]]470;471 %select0 = select i1 %cond, float 0x7FF8000000000000, float %x472 %select1 = select i1 %cond, float 0x7FF0000000000000, float %select0473 ret float %select1474}475 476define nofpclass(inf) float @ret_nofpclass_inf__select_chain_inf_nan_1(i1 %cond, float %x) {477; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__select_chain_inf_nan_1478; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {479; CHECK-NEXT: ret float 0x7FF8000000000000480;481 %select0 = select i1 %cond, float 0x7FF8000000000000, float %x482 %select1 = select i1 %cond, float %select0, float 0x7FF0000000000000483 ret float %select1484}485 486; Simplify to fabs %x487define nofpclass(inf) float @ret_nofpclass_inf__fabs_select_ninf_rhs(i1 %cond, float %x) {488; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__fabs_select_ninf_rhs489; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {490; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])491; CHECK-NEXT: ret float [[TMP1]]492;493 %select = select i1 %cond, float %x, float 0xFFF0000000000000494 %fabs = call float @llvm.fabs.f32(float %select)495 ret float %fabs496}497 498; Simplify to fabs %x499define nofpclass(inf) float @ret_nofpclass_inf__fabs_select_pinf_rhs(i1 %cond, float %x) {500; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__fabs_select_pinf_rhs501; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {502; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])503; CHECK-NEXT: ret float [[TMP1]]504;505 %select = select i1 %cond, float %x, float 0x7FF0000000000000506 %fabs = call float @llvm.fabs.f32(float %select)507 ret float %fabs508}509 510define nofpclass(ninf nnorm nsub nzero) float @ret_nofpclass_no_negatives__fabs_select_pinf_rhs(i1 %cond, float %x) {511; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_nofpclass_no_negatives__fabs_select_pinf_rhs512; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {513; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])514; CHECK-NEXT: [[FABS:%.*]] = select i1 [[COND]], float [[TMP1]], float 0x7FF0000000000000515; CHECK-NEXT: ret float [[FABS]]516;517 %select = select i1 %cond, float %x, float 0x7FF0000000000000518 %fabs = call float @llvm.fabs.f32(float %select)519 ret float %fabs520}521 522; Fold to fabs(%x), preserving a possible nan's payload bits523define nofpclass(pinf pnorm psub pzero) float @ret_nofpclass_no_positives__fabs_select_pinf_rhs(i1 %cond, float %x) {524; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @ret_nofpclass_no_positives__fabs_select_pinf_rhs525; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {526; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])527; CHECK-NEXT: ret float [[TMP1]]528;529 %select = select i1 %cond, float %x, float 0x7FF0000000000000530 %fabs = call float @llvm.fabs.f32(float %select)531 ret float %fabs532}533 534define nofpclass(nan ninf nnorm nsub nzero) float @ret_nofpclass_no_negatives_nan__fabs_select_pinf_rhs(i1 %cond, float %x) {535; CHECK-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @ret_nofpclass_no_negatives_nan__fabs_select_pinf_rhs536; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {537; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])538; CHECK-NEXT: [[FABS:%.*]] = select i1 [[COND]], float [[TMP1]], float 0x7FF0000000000000539; CHECK-NEXT: ret float [[FABS]]540;541 %select = select i1 %cond, float %x, float 0x7FF0000000000000542 %fabs = call float @llvm.fabs.f32(float %select)543 ret float %fabs544}545 546; Can fold to poison547define nofpclass(nan pinf pnorm psub pzero) float @ret_nofpclass_no_positives_nan__fabs_select_pinf_rhs(i1 %cond, float %x) {548; CHECK-LABEL: define nofpclass(nan pinf pzero psub pnorm) float @ret_nofpclass_no_positives_nan__fabs_select_pinf_rhs549; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {550; CHECK-NEXT: ret float poison551;552 %select = select i1 %cond, float %x, float 0x7FF0000000000000553 %fabs = call float @llvm.fabs.f32(float %select)554 ret float %fabs555}556 557; Simplify to fneg %x558define nofpclass(inf) float @ret_nofpclass_inf__fneg_select_ninf_rhs(i1 %cond, float %x) {559; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__fneg_select_ninf_rhs560; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {561; CHECK-NEXT: [[X_NEG:%.*]] = fneg float [[X]]562; CHECK-NEXT: ret float [[X_NEG]]563;564 %select = select i1 %cond, float %x, float 0xFFF0000000000000565 %fneg = fneg float %select566 ret float %fneg567}568 569; Simplify to fneg %x570define nofpclass(inf nnorm nsub nzero) float @ret_nofpclass_nonegatives_noinf___fneg_select_pinf_rhs(i1 %cond, float %x) {571; CHECK-LABEL: define nofpclass(inf nzero nsub nnorm) float @ret_nofpclass_nonegatives_noinf___fneg_select_pinf_rhs572; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {573; CHECK-NEXT: [[X_NEG:%.*]] = fneg float [[X]]574; CHECK-NEXT: ret float [[X_NEG]]575;576 %select = select i1 %cond, float %x, float 0x7FF0000000000000577 %fneg = fneg float %select578 ret float %fneg579}580 581; Simplify to fneg %x582define nofpclass(inf nnorm nsub nzero) float @ret_nofpclass_nonegatives_noinf___fneg_select_ninf_lhs(i1 %cond, float %x) {583; CHECK-LABEL: define nofpclass(inf nzero nsub nnorm) float @ret_nofpclass_nonegatives_noinf___fneg_select_ninf_lhs584; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {585; CHECK-NEXT: [[X_NEG:%.*]] = fneg float [[X]]586; CHECK-NEXT: ret float [[X_NEG]]587;588 %select = select i1 %cond, float 0xFFF0000000000000, float %x589 %fneg = fneg float %select590 ret float %fneg591}592 593define nofpclass(pzero psub pnorm pinf) float @ret_nofpclass_nopositives___fneg_select_pinf_rhs(i1 %cond, float %x) {594; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @ret_nofpclass_nopositives___fneg_select_pinf_rhs595; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {596; CHECK-NEXT: [[X_NEG:%.*]] = fneg float [[X]]597; CHECK-NEXT: [[FNEG:%.*]] = select i1 [[COND]], float [[X_NEG]], float 0xFFF0000000000000598; CHECK-NEXT: ret float [[FNEG]]599;600 %select = select i1 %cond, float %x, float 0x7FF0000000000000601 %fneg = fneg float %select602 ret float %fneg603}604 605; Fold to fneg fabs606define nofpclass(inf) float @ret_nofpclass_inf__fneg_fabs_select_pinf_rhs(i1 %cond, float %x) {607; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__fneg_fabs_select_pinf_rhs608; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {609; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])610; CHECK-NEXT: [[DOTNEG:%.*]] = fneg float [[TMP1]]611; CHECK-NEXT: ret float [[DOTNEG]]612;613 %select = select i1 %cond, float %x, float 0x7FF0000000000000614 %fabs = call float @llvm.fabs.f32(float %select)615 %fneg = fneg float %fabs616 ret float %fneg617}618 619; Fold to fneg fabs, may need to preserve a nan payload620define nofpclass(ninf nnorm nsub nzero) float @ret_nofpclass_nonegatives__fneg_fabs_select_pinf_rhs(i1 %cond, float %x) {621; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_nofpclass_nonegatives__fneg_fabs_select_pinf_rhs622; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {623; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])624; CHECK-NEXT: [[DOTNEG:%.*]] = fneg float [[TMP1]]625; CHECK-NEXT: ret float [[DOTNEG]]626;627 %select = select i1 %cond, float %x, float 0x7FF0000000000000628 %fabs = call float @llvm.fabs.f32(float %select)629 %fneg = fneg float %fabs630 ret float %fneg631}632 633 634; Fold to poison635define nofpclass(nan ninf nnorm nsub nzero) float @ret_nofpclass_nonegatives_nonan__fneg_fabs_select_pinf_rhs(i1 %cond, float %x) {636; CHECK-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @ret_nofpclass_nonegatives_nonan__fneg_fabs_select_pinf_rhs637; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {638; CHECK-NEXT: ret float poison639;640 %select = select i1 %cond, float %x, float 0x7FF0000000000000641 %fabs = call float @llvm.fabs.f32(float %select)642 %fneg = fneg float %fabs643 ret float %fneg644}645 646; should fold to ret copysign(%x)647define nofpclass(inf) float @ret_nofpclass_inf__copysign_unknown_select_pinf_rhs(i1 %cond, float %x, float %unknown.sign) {648; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__copysign_unknown_select_pinf_rhs649; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], float [[UNKNOWN_SIGN:%.*]]) {650; CHECK-NEXT: [[COPYSIGN:%.*]] = call float @llvm.copysign.f32(float [[X]], float [[UNKNOWN_SIGN]])651; CHECK-NEXT: ret float [[COPYSIGN]]652;653 %select = select i1 %cond, float %x, float 0x7FF0000000000000654 %copysign = call float @llvm.copysign.f32(float %select, float %unknown.sign)655 ret float %copysign656}657 658define nofpclass(inf) float @ret_nofpclass_inf__copysign_positive_select_pinf_rhs(i1 %cond, float %x) {659; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__copysign_positive_select_pinf_rhs660; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {661; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])662; CHECK-NEXT: ret float [[TMP1]]663;664 %select = select i1 %cond, float %x, float 0x7FF0000000000000665 %copysign = call float @llvm.copysign.f32(float %select, float 1.0)666 ret float %copysign667}668 669define nofpclass(inf) float @ret_nofpclass_inf__copysign_negative_select_pinf_rhs(i1 %cond, float %x) {670; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__copysign_negative_select_pinf_rhs671; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {672; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])673; CHECK-NEXT: [[DOTNEG:%.*]] = fneg float [[TMP1]]674; CHECK-NEXT: ret float [[DOTNEG]]675;676 %select = select i1 %cond, float %x, float 0x7FF0000000000000677 %copysign = call float @llvm.copysign.f32(float %select, float -1.0)678 ret float %copysign679}680 681; can't fold to fneg(fabs(x))682define nofpclass(pinf pnorm psub pzero) float @ret_nofpclass_nopositives_copysign(float %x, float %unknown.sign) {683; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @ret_nofpclass_nopositives_copysign684; CHECK-SAME: (float [[X:%.*]], float [[UNKNOWN_SIGN:%.*]]) {685; CHECK-NEXT: [[COPYSIGN:%.*]] = call float @llvm.copysign.f32(float [[X]], float [[UNKNOWN_SIGN]])686; CHECK-NEXT: ret float [[COPYSIGN]]687;688 %copysign = call float @llvm.copysign.f32(float %x, float %unknown.sign)689 ret float %copysign690}691 692; can fold to fneg(fabs(x))693define nofpclass(pinf pnorm psub pzero) float @ret_nofpclass_nopositives_copysign_nnan_flag(float %x, float %unknown.sign) {694; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @ret_nofpclass_nopositives_copysign_nnan_flag695; CHECK-SAME: (float [[X:%.*]], float [[UNKNOWN_SIGN:%.*]]) {696; CHECK-NEXT: [[TMP1:%.*]] = call nnan float @llvm.fabs.f32(float [[X]])697; CHECK-NEXT: [[COPYSIGN:%.*]] = fneg nnan float [[TMP1]]698; CHECK-NEXT: ret float [[COPYSIGN]]699;700 %copysign = call nnan float @llvm.copysign.f32(float %x, float %unknown.sign)701 ret float %copysign702}703 704; can fold to fneg(fabs(x))705define nofpclass(pnorm psub pzero) float @ret_nofpclass_nopositive_finites_copysign_nnan_ninf_flag(float %x, float %unknown.sign) {706; CHECK-LABEL: define nofpclass(pzero psub pnorm) float @ret_nofpclass_nopositive_finites_copysign_nnan_ninf_flag707; CHECK-SAME: (float [[X:%.*]], float [[UNKNOWN_SIGN:%.*]]) {708; CHECK-NEXT: [[TMP1:%.*]] = call nnan ninf float @llvm.fabs.f32(float [[X]])709; CHECK-NEXT: [[COPYSIGN:%.*]] = fneg nnan ninf float [[TMP1]]710; CHECK-NEXT: ret float [[COPYSIGN]]711;712 %copysign = call nnan ninf float @llvm.copysign.f32(float %x, float %unknown.sign)713 ret float %copysign714}715 716; can't fold to fneg(fabs(x))717define nofpclass(nan pinf pnorm psub pzero) float @ret_nofpclass_nopositives_nonan_copysign(float %x, float %unknown.sign) {718; CHECK-LABEL: define nofpclass(nan pinf pzero psub pnorm) float @ret_nofpclass_nopositives_nonan_copysign719; CHECK-SAME: (float [[X:%.*]], float [[UNKNOWN_SIGN:%.*]]) {720; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])721; CHECK-NEXT: [[COPYSIGN:%.*]] = fneg float [[TMP1]]722; CHECK-NEXT: ret float [[COPYSIGN]]723;724 %copysign = call float @llvm.copysign.f32(float %x, float %unknown.sign)725 ret float %copysign726}727 728; can't fold to fabs(x)729define nofpclass(ninf nnorm nsub nzero) float @ret_nofpclass_nonegatives_copysign(float %x, float %unknown.sign) {730; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_nofpclass_nonegatives_copysign731; CHECK-SAME: (float [[X:%.*]], float [[UNKNOWN_SIGN:%.*]]) {732; CHECK-NEXT: [[COPYSIGN:%.*]] = call float @llvm.copysign.f32(float [[X]], float [[UNKNOWN_SIGN]])733; CHECK-NEXT: ret float [[COPYSIGN]]734;735 %copysign = call float @llvm.copysign.f32(float %x, float %unknown.sign)736 ret float %copysign737}738 739; can fold to fabs(x)740define nofpclass(ninf nnorm nsub nzero) float @ret_nofpclass_nonegatives_copysign_nnan_flag(float %x, float %unknown.sign) {741; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_nofpclass_nonegatives_copysign_nnan_flag742; CHECK-SAME: (float [[X:%.*]], float [[UNKNOWN_SIGN:%.*]]) {743; CHECK-NEXT: [[COPYSIGN:%.*]] = call nnan float @llvm.fabs.f32(float [[X]])744; CHECK-NEXT: ret float [[COPYSIGN]]745;746 %copysign = call nnan float @llvm.copysign.f32(float %x, float %unknown.sign)747 ret float %copysign748}749 750; can fold to fabs(x)751define nofpclass(nan ninf nnorm nsub nzero) float @ret_nofpclass_nonegatives_nonan_copysign(float %x, float %unknown.sign) {752; CHECK-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @ret_nofpclass_nonegatives_nonan_copysign753; CHECK-SAME: (float [[X:%.*]], float [[UNKNOWN_SIGN:%.*]]) {754; CHECK-NEXT: [[COPYSIGN:%.*]] = call float @llvm.fabs.f32(float [[X]])755; CHECK-NEXT: ret float [[COPYSIGN]]756;757 %copysign = call float @llvm.copysign.f32(float %x, float %unknown.sign)758 ret float %copysign759}760 761define nofpclass(pinf pnorm psub pzero) float @ret_nofpclass_nopositives__copysign_fabs_select_pinf_rhs(i1 %cond, float %x, float %sign) {762; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @ret_nofpclass_nopositives__copysign_fabs_select_pinf_rhs763; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], float [[SIGN:%.*]]) {764; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])765; CHECK-NEXT: ret float [[TMP1]]766;767 %select = select i1 %cond, float %x, float 0x7FF0000000000000768 %fabs.sign = call float @llvm.fabs.f32(float %sign)769 %copysign = call float @llvm.copysign.f32(float %select, float %fabs.sign)770 ret float %copysign771}772 773; Can fold to copysign %x774define nofpclass(inf nnorm nsub nzero) float @ret_nofpclass_no_negatives_noinf__copysign_unknown_select_pinf_rhs(i1 %cond, float %x, float %unknown.sign) {775; CHECK-LABEL: define nofpclass(inf nzero nsub nnorm) float @ret_nofpclass_no_negatives_noinf__copysign_unknown_select_pinf_rhs776; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], float [[UNKNOWN_SIGN:%.*]]) {777; CHECK-NEXT: [[COPYSIGN:%.*]] = call float @llvm.copysign.f32(float [[X]], float [[UNKNOWN_SIGN]])778; CHECK-NEXT: ret float [[COPYSIGN]]779;780 %select = select i1 %cond, float %x, float 0x7FF0000000000000781 %copysign = call float @llvm.copysign.f32(float %select, float %unknown.sign)782 ret float %copysign783}784 785; Can fold to copysign %x786define nofpclass(inf pnorm psub pzero) float @ret_nofpclass_no_positives_noinf__copysign_unknown_select_pinf_rhs(i1 %cond, float %x, float %unknown.sign) {787; CHECK-LABEL: define nofpclass(inf pzero psub pnorm) float @ret_nofpclass_no_positives_noinf__copysign_unknown_select_pinf_rhs788; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], float [[UNKNOWN_SIGN:%.*]]) {789; CHECK-NEXT: [[COPYSIGN:%.*]] = call float @llvm.copysign.f32(float [[X]], float [[UNKNOWN_SIGN]])790; CHECK-NEXT: ret float [[COPYSIGN]]791;792 %select = select i1 %cond, float %x, float 0x7FF0000000000000793 %copysign = call float @llvm.copysign.f32(float %select, float %unknown.sign)794 ret float %copysign795}796 797; Can't fold because it could have nan payload bits798define nofpclass(ninf nnorm nsub nzero) float @ret_nofpclass_no_negatives__copysign_unknown_select_pinf_rhs(i1 %cond, float %x, float %unknown.sign) {799; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_nofpclass_no_negatives__copysign_unknown_select_pinf_rhs800; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], float [[UNKNOWN_SIGN:%.*]]) {801; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[X]], float 0x7FF0000000000000802; CHECK-NEXT: [[COPYSIGN:%.*]] = call float @llvm.copysign.f32(float [[SELECT]], float [[UNKNOWN_SIGN]])803; CHECK-NEXT: ret float [[COPYSIGN]]804;805 %select = select i1 %cond, float %x, float 0x7FF0000000000000806 %copysign = call float @llvm.copysign.f32(float %select, float %unknown.sign)807 ret float %copysign808}809 810; Can't fold because it could be nan811define nofpclass(pinf pnorm psub pzero) float @ret_nofpclass_no_positives__copysign_unknown_select_pinf_rhs(i1 %cond, float %x, float %unknown.sign) {812; CHECK-LABEL: define nofpclass(pinf pzero psub pnorm) float @ret_nofpclass_no_positives__copysign_unknown_select_pinf_rhs813; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], float [[UNKNOWN_SIGN:%.*]]) {814; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[X]], float 0x7FF0000000000000815; CHECK-NEXT: [[COPYSIGN:%.*]] = call float @llvm.copysign.f32(float [[SELECT]], float [[UNKNOWN_SIGN]])816; CHECK-NEXT: ret float [[COPYSIGN]]817;818 %select = select i1 %cond, float %x, float 0x7FF0000000000000819 %copysign = call float @llvm.copysign.f32(float %select, float %unknown.sign)820 ret float %copysign821}822 823; Could fold to copysign with constant824define nofpclass(nan ninf nnorm nsub nzero) float @ret_nofpclass_no_negatives_nonan__copysign_unknown_select_pinf_rhs(i1 %cond, float %x, float %unknown.sign) {825; CHECK-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @ret_nofpclass_no_negatives_nonan__copysign_unknown_select_pinf_rhs826; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], float [[UNKNOWN_SIGN:%.*]]) {827; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])828; CHECK-NEXT: [[COPYSIGN:%.*]] = select i1 [[COND]], float [[TMP1]], float 0x7FF0000000000000829; CHECK-NEXT: ret float [[COPYSIGN]]830;831 %select = select i1 %cond, float %x, float 0x7FF0000000000000832 %copysign = call float @llvm.copysign.f32(float %select, float %unknown.sign)833 ret float %copysign834}835 836; Could fold to copysign %x with constant837define nofpclass(nan pinf pnorm psub pzero) float @ret_nofpclass_no_positives_nonan__copysign_unknown_select_pinf_rhs(i1 %cond, float %x, float %unknown.sign) {838; CHECK-LABEL: define nofpclass(nan pinf pzero psub pnorm) float @ret_nofpclass_no_positives_nonan__copysign_unknown_select_pinf_rhs839; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], float [[UNKNOWN_SIGN:%.*]]) {840; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X]])841; CHECK-NEXT: [[DOTNEG:%.*]] = fneg float [[TMP1]]842; CHECK-NEXT: [[COPYSIGN:%.*]] = select i1 [[COND]], float [[DOTNEG]], float 0xFFF0000000000000843; CHECK-NEXT: ret float [[COPYSIGN]]844;845 %select = select i1 %cond, float %x, float 0x7FF0000000000000846 %copysign = call float @llvm.copysign.f32(float %select, float %unknown.sign)847 ret float %copysign848}849 850; Do nothing851define nofpclass(ninf nnorm nsub nzero) float @ret_nofpclass_negatives__select_clamp_neg_to_zero(float %x) {852; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_nofpclass_negatives__select_clamp_neg_to_zero853; CHECK-SAME: (float [[X:%.*]]) {854; CHECK-NEXT: [[IS_LT_ZERO:%.*]] = fcmp olt float [[X]], 0.000000e+00855; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_LT_ZERO]], float 0.000000e+00, float [[X]]856; CHECK-NEXT: ret float [[SELECT]]857;858 %is.lt.zero = fcmp olt float %x, 0.0859 %select = select i1 %is.lt.zero, float 0.0, float %x860 ret float %select861}862 863; Can fold to ret %x, assumed to be nan864define nofpclass(ninf nnorm nsub nzero) float @ret_nofpclass_negatives__select_clamp_pos_to_zero(float %x) {865; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_nofpclass_negatives__select_clamp_pos_to_zero866; CHECK-SAME: (float [[X:%.*]]) {867; CHECK-NEXT: [[IS_GT_ZERO:%.*]] = fcmp ogt float [[X]], 0.000000e+00868; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_GT_ZERO]], float 0.000000e+00, float [[X]]869; CHECK-NEXT: ret float [[SELECT]]870;871 %is.gt.zero = fcmp ogt float %x, 0.0872 %select = select i1 %is.gt.zero, float 0.0, float %x873 ret float %select874}875 876; Can fold to ret +0877define nofpclass(nan ninf nnorm nsub nzero) float @ret_nofpclass_nan_negatives__select_clamp_pos_to_zero(float %x) {878; CHECK-LABEL: define nofpclass(nan ninf nzero nsub nnorm) float @ret_nofpclass_nan_negatives__select_clamp_pos_to_zero879; CHECK-SAME: (float [[X:%.*]]) {880; CHECK-NEXT: [[IS_GT_ZERO:%.*]] = fcmp ogt float [[X]], 0.000000e+00881; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_GT_ZERO]], float 0.000000e+00, float [[X]]882; CHECK-NEXT: ret float [[SELECT]]883;884 %is.gt.zero = fcmp ogt float %x, 0.0885 %select = select i1 %is.gt.zero, float 0.0, float %x886 ret float %select887}888 889; Can fold to ret poison890define nofpclass(nan ninf nnorm nsub zero) float @ret_nofpclass_nan_negatives_zero__select_clamp_pos_to_zero(float %x) {891; CHECK-LABEL: define nofpclass(nan ninf zero nsub nnorm) float @ret_nofpclass_nan_negatives_zero__select_clamp_pos_to_zero892; CHECK-SAME: (float [[X:%.*]]) {893; CHECK-NEXT: ret float [[X]]894;895 %is.gt.zero = fcmp ogt float %x, 0.0896 %select = select i1 %is.gt.zero, float 0.0, float %x897 ret float %select898}899 900; Can fold to ret %x, assumed to be nan901define nofpclass(ninf nnorm nsub zero) float @ret_nofpclass_negatives_zero__select_clamp_pos_to_zero(float %x) {902; CHECK-LABEL: define nofpclass(ninf zero nsub nnorm) float @ret_nofpclass_negatives_zero__select_clamp_pos_to_zero903; CHECK-SAME: (float [[X:%.*]]) {904; CHECK-NEXT: ret float [[X]]905;906 %is.gt.zero = fcmp ogt float %x, 0.0907 %select = select i1 %is.gt.zero, float 0.0, float %x908 ret float %select909}910 911; Assume should allow folding ret %y912define nofpclass(inf) float @ret_nofpclass_noinfs__assumed_isinf__select_pinf_lhs(i1 %cond, float %x, float %y) {913; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_noinfs__assumed_isinf__select_pinf_lhs914; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], float [[Y:%.*]]) {915; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])916; CHECK-NEXT: [[X_IS_INF:%.*]] = fcmp oeq float [[FABS_X]], 0x7FF0000000000000917; CHECK-NEXT: call void @llvm.assume(i1 [[X_IS_INF]])918; CHECK-NEXT: ret float [[Y]]919;920 %fabs.x = call float @llvm.fabs.f32(float %x)921 %x.is.inf = fcmp oeq float %fabs.x, 0x7FF0000000000000922 call void @llvm.assume(i1 %x.is.inf)923 %select = select i1 %cond, float %x, float %y924 ret float %select925}926 927; Ideally should be able to fold out everything after the exp2 call.928define nofpclass(nan inf nzero nsub nnorm) float @powr_issue64870(float nofpclass(nan inf) %x, float nofpclass(nan inf) %y) {929; CHECK-LABEL: define nofpclass(nan inf nzero nsub nnorm) float @powr_issue64870930; CHECK-SAME: (float nofpclass(nan inf) [[X:%.*]], float nofpclass(nan inf) [[Y:%.*]]) {931; CHECK-NEXT: entry:932; CHECK-NEXT: [[I:%.*]] = tail call float @llvm.fabs.f32(float [[X]])933; CHECK-NEXT: [[I1:%.*]] = tail call float @llvm.log2.f32(float [[I]])934; CHECK-NEXT: [[I2:%.*]] = fmul float [[I1]], [[Y]]935; CHECK-NEXT: [[I3:%.*]] = tail call nofpclass(ninf nzero nsub nnorm) float @llvm.exp2.f32(float [[I2]])936; CHECK-NEXT: [[I6:%.*]] = fcmp oeq float [[X]], 0.000000e+00937; CHECK-NEXT: [[I7:%.*]] = select i1 [[I6]], float 0.000000e+00, float [[I3]]938; CHECK-NEXT: [[I8:%.*]] = fcmp oeq float [[Y]], 0.000000e+00939; CHECK-NEXT: [[I11:%.*]] = fcmp oeq float [[X]], 1.000000e+00940; CHECK-NEXT: [[TMP0:%.*]] = select i1 [[I11]], i1 true, i1 [[I8]]941; CHECK-NEXT: [[I12:%.*]] = select i1 [[TMP0]], float 1.000000e+00, float [[I7]]942; CHECK-NEXT: ret float [[I12]]943;944entry:945 %i = tail call float @llvm.fabs.f32(float %x)946 %i1 = tail call float @llvm.log2.f32(float %i)947 %i2 = fmul float %i1, %y948 %i3 = tail call nofpclass(ninf nzero nsub nnorm) float @llvm.exp2.f32(float %i2)949 %i4 = fcmp olt float %y, 0.000000e+00950 %i5 = select i1 %i4, float 0x7FF0000000000000, float 0.000000e+00951 %i6 = fcmp oeq float %x, 0.000000e+00952 %i7 = select i1 %i6, float %i5, float %i3953 %i8 = fcmp oeq float %y, 0.000000e+00954 %i9 = select i1 %i6, float 0x7FF8000000000000, float 1.000000e+00955 %i10 = select i1 %i8, float %i9, float %i7956 %i11 = fcmp oeq float %x, 1.000000e+00957 %i12 = select i1 %i11, float 1.000000e+00, float %i10958 %i13 = fcmp olt float %x, 0.000000e+00959 %i14 = select i1 %i13, float 0x7FF8000000000000, float %i12960 ret float %i14961}962 963; Different implementation of powr964define nofpclass(nan inf nzero nsub nnorm) float @test_powr_issue64870_2(float nofpclass(nan inf) %arg, float nofpclass(nan inf) %arg1) #0 {965; CHECK-LABEL: define nofpclass(nan inf nzero nsub nnorm) float @test_powr_issue64870_2966; CHECK-SAME: (float nofpclass(nan inf) [[ARG:%.*]], float nofpclass(nan inf) [[ARG1:%.*]]) {967; CHECK-NEXT: bb:968; CHECK-NEXT: [[I:%.*]] = fcmp olt float [[ARG]], 0.000000e+00969; CHECK-NEXT: [[I2:%.*]] = select i1 [[I]], float 0x7FF8000000000000, float [[ARG]]970; CHECK-NEXT: [[I3:%.*]] = tail call float @llvm.log2.f32(float noundef [[I2]])971; CHECK-NEXT: [[I4:%.*]] = select i1 [[I]], float 0x7FF8000000000000, float [[ARG1]]972; CHECK-NEXT: [[I5:%.*]] = fmul float [[I4]], [[I3]]973; CHECK-NEXT: [[I6:%.*]] = tail call noundef nofpclass(ninf nzero nsub nnorm) float @llvm.exp2.f32(float noundef [[I5]])974; CHECK-NEXT: [[I10:%.*]] = fcmp oeq float [[I2]], 0.000000e+00975; CHECK-NEXT: [[I12:%.*]] = select i1 [[I10]], float 0.000000e+00, float [[I6]]976; CHECK-NEXT: ret float [[I12]]977;978bb:979 %i = fcmp olt float %arg, 0.000000e+00980 %i2 = select i1 %i, float 0x7FF8000000000000, float %arg981 %i3 = tail call float @llvm.log2.f32(float noundef %i2) #2982 %i4 = select i1 %i, float 0x7FF8000000000000, float %arg1983 %i5 = fmul float %i4, %i3984 %i6 = tail call noundef nofpclass(ninf nzero nsub nnorm) float @llvm.exp2.f32(float noundef %i5)985 %i7 = fcmp olt float %i4, 0.000000e+00986 %i8 = select i1 %i7, float 0x7FF0000000000000, float 0.000000e+00987 %i9 = fcmp ueq float %i4, 0.000000e+00988 %i10 = fcmp oeq float %i2, 0.000000e+00989 %i11 = select i1 %i9, float 0x7FF8000000000000, float %i8990 %i12 = select i1 %i10, float %i11, float %i6991 ret float %i12992}993 994; implementation of pow with some prunable cases995define nofpclass(nan inf) float @pow_f32(float nofpclass(nan inf) %arg, float nofpclass(nan inf) %arg1) #0 {996; CHECK-LABEL: define nofpclass(nan inf) float @pow_f32997; CHECK-SAME: (float nofpclass(nan inf) [[ARG:%.*]], float nofpclass(nan inf) [[ARG1:%.*]]) {998; CHECK-NEXT: bb:999; CHECK-NEXT: [[I:%.*]] = tail call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float noundef [[ARG]])1000; CHECK-NEXT: [[I2:%.*]] = tail call float @llvm.log2.f32(float noundef [[I]])1001; CHECK-NEXT: [[I3:%.*]] = fmul float [[I2]], [[ARG1]]1002; CHECK-NEXT: [[I4:%.*]] = tail call noundef float @llvm.exp2.f32(float noundef [[I3]])1003; CHECK-NEXT: [[I5:%.*]] = tail call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float noundef [[ARG1]])1004; CHECK-NEXT: [[I6:%.*]] = tail call float @llvm.trunc.f32(float noundef [[I5]])1005; CHECK-NEXT: [[I7:%.*]] = fcmp oeq float [[I6]], [[I5]]1006; CHECK-NEXT: [[I8:%.*]] = fmul float [[I5]], 5.000000e-011007; CHECK-NEXT: [[I9:%.*]] = tail call float @llvm.trunc.f32(float noundef [[I8]])1008; CHECK-NEXT: [[I10:%.*]] = fcmp une float [[I9]], [[I8]]1009; CHECK-NEXT: [[I11:%.*]] = and i1 [[I7]], [[I10]]1010; CHECK-NEXT: [[I12:%.*]] = select i1 [[I11]], float [[ARG]], float 1.000000e+001011; CHECK-NEXT: [[I13:%.*]] = tail call noundef float @llvm.copysign.f32(float noundef [[I4]], float noundef [[I12]])1012; CHECK-NEXT: [[I17:%.*]] = fcmp oeq float [[ARG]], 0.000000e+001013; CHECK-NEXT: [[TMP0:%.*]] = tail call nofpclass(nan sub norm) float @llvm.copysign.f32(float 0.000000e+00, float [[ARG]])1014; CHECK-NEXT: [[I22:%.*]] = select i1 [[I11]], float [[TMP0]], float 0.000000e+001015; CHECK-NEXT: [[I23:%.*]] = select i1 [[I17]], float [[I22]], float [[I13]]1016; CHECK-NEXT: [[I24:%.*]] = fcmp oeq float [[ARG]], 1.000000e+001017; CHECK-NEXT: [[I25:%.*]] = fcmp oeq float [[ARG1]], 0.000000e+001018; CHECK-NEXT: [[I26:%.*]] = or i1 [[I24]], [[I25]]1019; CHECK-NEXT: [[I27:%.*]] = select i1 [[I26]], float 1.000000e+00, float [[I23]]1020; CHECK-NEXT: ret float [[I27]]1021;1022bb:1023 %i = tail call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float noundef %arg)1024 %i2 = tail call float @llvm.log2.f32(float noundef %i)1025 %i3 = fmul float %i2, %arg11026 %i4 = tail call noundef float @llvm.exp2.f32(float noundef %i3)1027 %i5 = tail call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float noundef %arg1)1028 %i6 = tail call float @llvm.trunc.f32(float noundef %i5)1029 %i7 = fcmp oeq float %i6, %i51030 %i8 = fmul float %i5, 5.000000e-011031 %i9 = tail call float @llvm.trunc.f32(float noundef %i8)1032 %i10 = fcmp une float %i9, %i81033 %i11 = and i1 %i7, %i101034 %i12 = select i1 %i11, float %arg, float 1.000000e+001035 %i13 = tail call noundef float @llvm.copysign.f32(float noundef %i4, float noundef %i12)1036 %i14 = fcmp olt float %arg, 0.000000e+001037 %i15 = select i1 %i7, float %i13, float 0x7FF80000000000001038 %i16 = select i1 %i14, float %i15, float %i131039 %i17 = fcmp oeq float %arg, 0.000000e+001040 %i18 = fcmp olt float %arg1, 0.000000e+001041 %i19 = xor i1 %i17, %i181042 %i20 = select i1 %i19, float 0.000000e+00, float 0x7FF00000000000001043 %i21 = select i1 %i11, float %arg, float 0.000000e+001044 %i22 = tail call noundef nofpclass(nan sub norm) float @llvm.copysign.f32(float noundef %i20, float noundef %i21)1045 %i23 = select i1 %i17, float %i22, float %i161046 %i24 = fcmp oeq float %arg, 1.000000e+001047 %i25 = fcmp oeq float %arg1, 0.000000e+001048 %i26 = or i1 %i24, %i251049 %i27 = select i1 %i26, float 1.000000e+00, float %i231050 ret float %i271051}1052 1053declare float @extern()1054 1055; Make sure nofpclass from arbitrary callsite is used, fold to %y1056define nofpclass(inf) float @ret_nofpclass_inf__select_nofpclass_call_only_inf(i1 %cond, float %y) {1057; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__select_nofpclass_call_only_inf1058; CHECK-SAME: (i1 [[COND:%.*]], float [[Y:%.*]]) {1059; CHECK-NEXT: [[MUST_BE_INF:%.*]] = call nofpclass(nan zero sub norm) float @extern()1060; CHECK-NEXT: ret float [[Y]]1061;1062 %must.be.inf = call nofpclass(nan norm zero sub) float @extern()1063 %select = select i1 %cond, float %must.be.inf, float %y1064 ret float %select1065}1066 1067define nofpclass(pinf) float @ret_nofpclass_pinf__nofpclass_call_only_inf(i1 %cond, float %y) {1068; CHECK-LABEL: define nofpclass(pinf) float @ret_nofpclass_pinf__nofpclass_call_only_inf1069; CHECK-SAME: (i1 [[COND:%.*]], float [[Y:%.*]]) {1070; CHECK-NEXT: [[MUST_BE_INF:%.*]] = call nofpclass(nan zero sub norm) float @extern()1071; CHECK-NEXT: ret float 0xFFF00000000000001072;1073 %must.be.inf = call nofpclass(nan norm zero sub) float @extern()1074 ret float %must.be.inf1075}1076 1077define nofpclass(ninf) float @ret_nofpclass_ninf__nofpclass_call_only_inf(i1 %cond, float %y) {1078; CHECK-LABEL: define nofpclass(ninf) float @ret_nofpclass_ninf__nofpclass_call_only_inf1079; CHECK-SAME: (i1 [[COND:%.*]], float [[Y:%.*]]) {1080; CHECK-NEXT: [[MUST_BE_INF:%.*]] = call nofpclass(nan zero sub norm) float @extern()1081; CHECK-NEXT: ret float 0x7FF00000000000001082;1083 %must.be.inf = call nofpclass(nan norm zero sub) float @extern()1084 ret float %must.be.inf1085}1086 1087define nofpclass(nzero) float @ret_nofpclass_nzero__nofpclass_call_only_zero(i1 %cond, float %y) {1088; CHECK-LABEL: define nofpclass(nzero) float @ret_nofpclass_nzero__nofpclass_call_only_zero1089; CHECK-SAME: (i1 [[COND:%.*]], float [[Y:%.*]]) {1090; CHECK-NEXT: [[MUST_BE_ZERO:%.*]] = call nofpclass(nan inf sub norm) float @extern()1091; CHECK-NEXT: ret float 0.000000e+001092;1093 %must.be.zero = call nofpclass(nan sub norm inf) float @extern()1094 ret float %must.be.zero1095}1096 1097define nofpclass(pzero) float @ret_nofpclass_pzero__nofpclass_call_only_zero(i1 %cond, float %y) {1098; CHECK-LABEL: define nofpclass(pzero) float @ret_nofpclass_pzero__nofpclass_call_only_zero1099; CHECK-SAME: (i1 [[COND:%.*]], float [[Y:%.*]]) {1100; CHECK-NEXT: [[MUST_BE_ZERO:%.*]] = call nofpclass(nan inf sub norm) float @extern()1101; CHECK-NEXT: ret float -0.000000e+001102;1103 %must.be.zero = call nofpclass(nan sub norm inf) float @extern()1104 ret float %must.be.zero1105}1106 1107; Should not fold this, should not assume payload/sign bits are canonical1108define nofpclass(qnan) float @ret_nofpclass_qnan__nofpclass_call_only_nan(i1 %cond, float %y) {1109; CHECK-LABEL: define nofpclass(qnan) float @ret_nofpclass_qnan__nofpclass_call_only_nan1110; CHECK-SAME: (i1 [[COND:%.*]], float [[Y:%.*]]) {1111; CHECK-NEXT: [[MUST_BE_NAN:%.*]] = call nofpclass(inf zero sub norm) float @extern()1112; CHECK-NEXT: ret float [[MUST_BE_NAN]]1113;1114 %must.be.nan = call nofpclass(inf norm zero sub) float @extern()1115 ret float %must.be.nan1116}1117 1118; Should not fold this, should not assume payload/sign bits are canonical1119define nofpclass(snan) float @ret_nofpclass_snan__nofpclass_call_only_nan(i1 %cond, float %y) {1120; CHECK-LABEL: define nofpclass(snan) float @ret_nofpclass_snan__nofpclass_call_only_nan1121; CHECK-SAME: (i1 [[COND:%.*]], float [[Y:%.*]]) {1122; CHECK-NEXT: [[MUST_BE_NAN:%.*]] = call nofpclass(inf zero sub norm) float @extern()1123; CHECK-NEXT: ret float [[MUST_BE_NAN]]1124;1125 %must.be.nan = call nofpclass(inf norm zero sub) float @extern()1126 ret float %must.be.nan1127}1128 1129; Assume call should allow folding this to %y1130; TODO: Not working, multiple user problem.1131define nofpclass(inf) float @ret_nofpclass_inf__select_assumed_call_result_only_inf(i1 %cond, float %y) {1132; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__select_assumed_call_result_only_inf1133; CHECK-SAME: (i1 [[COND:%.*]], float [[Y:%.*]]) {1134; CHECK-NEXT: [[MUST_BE_INF:%.*]] = call float @extern()1135; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[MUST_BE_INF]])1136; CHECK-NEXT: [[IS_INF:%.*]] = fcmp oeq float [[FABS]], 0x7FF00000000000001137; CHECK-NEXT: call void @llvm.assume(i1 [[IS_INF]])1138; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[MUST_BE_INF]], float [[Y]]1139; CHECK-NEXT: ret float [[SELECT]]1140;1141 %must.be.inf = call float @extern()1142 %fabs = call float @llvm.fabs.f32(float %must.be.inf)1143 %is.inf = fcmp oeq float %fabs, 0x7FF00000000000001144 call void @llvm.assume(i1 %is.inf)1145 %select = select i1 %cond, float %must.be.inf, float %y1146 ret float %select1147}1148 1149define nofpclass(inf) float @ret_nofpclass_inf__simple_phi_inf_or_unknown(i1 %cond, float %x) {1150; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__simple_phi_inf_or_unknown1151; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {1152; CHECK-NEXT: entry:1153; CHECK-NEXT: br i1 [[COND]], label [[BB0:%.*]], label [[RET:%.*]]1154; CHECK: bb0:1155; CHECK-NEXT: br label [[RET]]1156; CHECK: ret:1157; CHECK-NEXT: [[PHI:%.*]] = phi float [ 0x7FF0000000000000, [[ENTRY:%.*]] ], [ [[X]], [[BB0]] ]1158; CHECK-NEXT: ret float [[PHI]]1159;1160entry:1161 br i1 %cond, label %bb0, label %ret1162 1163bb0:1164 br label %ret1165 1166ret:1167 %phi = phi float [ 0x7FF0000000000000, %entry ], [ %x, %bb0 ]1168 ret float %phi1169}1170 1171declare i1 @loop.cond()1172 1173declare float @loop.func()1174 1175 1176; Should be able to fold inf initial value to poison1177define nofpclass(inf) float @ret_nofpclass_inf__phi_0(i1 %cond0, float %unknown) {1178; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__phi_01179; CHECK-SAME: (i1 [[COND0:%.*]], float [[UNKNOWN:%.*]]) {1180; CHECK-NEXT: entry:1181; CHECK-NEXT: br i1 [[COND0]], label [[LOOP:%.*]], label [[RET:%.*]]1182; CHECK: loop:1183; CHECK-NEXT: [[PHI_LOOP:%.*]] = phi float [ 0x7FF0000000000000, [[ENTRY:%.*]] ], [ [[LOOP_FUNC:%.*]], [[LOOP]] ]1184; CHECK-NEXT: [[LOOP_FUNC]] = call nofpclass(nan) float @loop.func()1185; CHECK-NEXT: [[LOOP_COND:%.*]] = call i1 @loop.cond()1186; CHECK-NEXT: br i1 [[LOOP_COND]], label [[RET]], label [[LOOP]]1187; CHECK: ret:1188; CHECK-NEXT: [[PHI_RET:%.*]] = phi float [ 0.000000e+00, [[ENTRY]] ], [ [[PHI_LOOP]], [[LOOP]] ]1189; CHECK-NEXT: ret float [[PHI_RET]]1190;1191entry:1192 br i1 %cond0, label %loop, label %ret1193 1194loop:1195 %phi.loop = phi float [ 0x7FF0000000000000, %entry ], [ %loop.func, %loop ]1196 %loop.func = call nofpclass(nan) float @loop.func()1197 %loop.cond = call i1 @loop.cond()1198 br i1 %loop.cond, label %ret, label %loop1199 1200ret:1201 %phi.ret = phi float [ 0.0, %entry ], [ %phi.loop, %loop ]1202 ret float %phi.ret1203}1204 1205; fold to ret 01206define nofpclass(inf) float @ret_nofpclass_inf__recursive_phi_0(i1 %cond0, float %unknown) {1207; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__recursive_phi_01208; CHECK-SAME: (i1 [[COND0:%.*]], float [[UNKNOWN:%.*]]) {1209; CHECK-NEXT: entry:1210; CHECK-NEXT: br i1 [[COND0]], label [[LOOP:%.*]], label [[RET:%.*]]1211; CHECK: loop:1212; CHECK-NEXT: [[LOOP_COND:%.*]] = call i1 @loop.cond()1213; CHECK-NEXT: br i1 [[LOOP_COND]], label [[RET]], label [[LOOP]]1214; CHECK: ret:1215; CHECK-NEXT: ret float 0.000000e+001216;1217entry:1218 br i1 %cond0, label %loop, label %ret1219 1220loop:1221 %phi.loop = phi float [ 0x7FF0000000000000, %entry ], [ %phi.loop, %loop ]1222 %loop.cond = call i1 @loop.cond()1223 br i1 %loop.cond, label %ret, label %loop1224 1225ret:1226 %phi.ret = phi float [ 0.0, %entry ], [ %phi.loop, %loop ]1227 ret float %phi.ret1228}1229 1230; fold to ret poison1231define nofpclass(inf) float @ret_nofpclass_inf__recursive_phi_1(i1 %cond0, float %unknown) {1232; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__recursive_phi_11233; CHECK-SAME: (i1 [[COND0:%.*]], float [[UNKNOWN:%.*]]) {1234; CHECK-NEXT: entry:1235; CHECK-NEXT: br i1 [[COND0]], label [[LOOP:%.*]], label [[RET:%.*]]1236; CHECK: loop:1237; CHECK-NEXT: [[LOOP_COND:%.*]] = call i1 @loop.cond()1238; CHECK-NEXT: br i1 [[LOOP_COND]], label [[RET]], label [[LOOP]]1239; CHECK: ret:1240; CHECK-NEXT: ret float poison1241;1242entry:1243 br i1 %cond0, label %loop, label %ret1244 1245loop:1246 %phi.loop = phi float [ 0x7FF0000000000000, %entry ], [ %phi.loop, %loop ]1247 %loop.cond = call i1 @loop.cond()1248 br i1 %loop.cond, label %ret, label %loop1249 1250ret:1251 %phi.ret = phi float [ 0x7FF0000000000000, %entry ], [ %phi.loop, %loop ]1252 ret float %phi.ret1253}1254 1255; Should be able to fold inf initial values to poison1256define nofpclass(inf) float @ret_nofpclass_inf__phi_switch_repeated_predecessor(i32 %switch, float %unknown) {1257; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__phi_switch_repeated_predecessor1258; CHECK-SAME: (i32 [[SWITCH:%.*]], float [[UNKNOWN:%.*]]) {1259; CHECK-NEXT: entry:1260; CHECK-NEXT: switch i32 [[SWITCH]], label [[RET:%.*]] [1261; CHECK-NEXT: i32 0, label [[LOOP:%.*]]1262; CHECK-NEXT: i32 1, label [[LOOP]]1263; CHECK-NEXT: ]1264; CHECK: loop:1265; CHECK-NEXT: [[PHI_LOOP:%.*]] = phi float [ 0x7FF0000000000000, [[ENTRY:%.*]] ], [ 0x7FF0000000000000, [[ENTRY]] ], [ [[UNKNOWN]], [[LOOP]] ]1266; CHECK-NEXT: [[LOOP_COND:%.*]] = call i1 @loop.cond()1267; CHECK-NEXT: br i1 [[LOOP_COND]], label [[RET]], label [[LOOP]]1268; CHECK: ret:1269; CHECK-NEXT: [[PHI_RET:%.*]] = phi float [ 0.000000e+00, [[ENTRY]] ], [ [[PHI_LOOP]], [[LOOP]] ]1270; CHECK-NEXT: ret float [[PHI_RET]]1271;1272entry:1273 switch i32 %switch, label %ret [1274 i32 0, label %loop1275 i32 1, label %loop1276 ]1277 1278loop:1279 %phi.loop = phi float [ 0x7FF0000000000000, %entry ], [ 0x7FF0000000000000, %entry ], [ %unknown, %loop ]1280 %loop.cond = call i1 @loop.cond()1281 br i1 %loop.cond, label %ret, label %loop1282 1283ret:1284 %phi.ret = phi float [ 0.0, %entry ], [ %phi.loop, %loop ]1285 ret float %phi.ret1286}1287 1288; Simplify to arithmetic.fence %x1289define nofpclass(inf) float @ret_nofpclass_inf__arithmetic_fence_select_pinf_rhs(i1 %cond, float %x) {1290; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__arithmetic_fence_select_pinf_rhs1291; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {1292; CHECK-NEXT: [[FENCE:%.*]] = call float @llvm.arithmetic.fence.f32(float [[X]])1293; CHECK-NEXT: ret float [[FENCE]]1294;1295 %select = select i1 %cond, float %x, float 0x7FF00000000000001296 %fence = call float @llvm.arithmetic.fence.f32(float %select)1297 ret float %fence1298}1299 1300; Can simplify to %x1301define nofpclass(pinf) float @ret_nofpclass_pinf__minnum_pinf(i1 %cond, float %x) {1302; CHECK-LABEL: define nofpclass(pinf) float @ret_nofpclass_pinf__minnum_pinf1303; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {1304; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X]], float 0x7FF0000000000000)1305; CHECK-NEXT: ret float [[MIN]]1306;1307 %min = call float @llvm.minnum.f32(float %x, float 0x7FF0000000000000)1308 ret float %min1309}1310 1311; Can fold to -inf1312define nofpclass(pinf) float @ret_nofpclass_pinf__minnum_ninf(i1 %cond, float %x) {1313; CHECK-LABEL: define nofpclass(pinf) float @ret_nofpclass_pinf__minnum_ninf1314; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {1315; CHECK-NEXT: ret float 0xFFF00000000000001316;1317 %min = call float @llvm.minnum.f32(float %x, float 0xFFF0000000000000)1318 ret float %min1319}1320 1321; Can simplify to %x1322define nofpclass(ninf) float @ret_nofpclass_ninf__maxnum_ninf(i1 %cond, float %x) {1323; CHECK-LABEL: define nofpclass(ninf) float @ret_nofpclass_ninf__maxnum_ninf1324; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {1325; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[X]], float 0xFFF0000000000000)1326; CHECK-NEXT: ret float [[MAX]]1327;1328 %max = call float @llvm.maxnum.f32(float %x, float 0xFFF0000000000000)1329 ret float %max1330}1331 1332; Can fold to +inf1333define nofpclass(ninf) float @ret_nofpclass_ninf__maxnum_pinf(i1 %cond, float %x) {1334; CHECK-LABEL: define nofpclass(ninf) float @ret_nofpclass_ninf__maxnum_pinf1335; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]]) {1336; CHECK-NEXT: ret float 0x7FF00000000000001337;1338 %max = call float @llvm.maxnum.f32(float %x, float 0x7FF0000000000000)1339 ret float %max1340}1341