2226 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=instcombine < %s | FileCheck %s3 4; Test and/or of fcmps that could be folded to llvm.is.fpclass5 6; --------------------------------------------------------------------7; Base pattern, !isfinite(x) || x == 0.08; --------------------------------------------------------------------9 10; Base pattern !isfinite(x) || x == 0.011define i1 @not_isfinite_or_zero_f16(half %x) {12; CHECK-LABEL: @not_isfinite_or_zero_f16(13; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 615)14; CHECK-NEXT: ret i1 [[CLASS]]15;16 %fabs = call half @llvm.fabs.f16(half %x)17 %cmpinf = fcmp ueq half %fabs, 0xH7C0018 %cmpzero = fcmp oeq half %x, 0xH000019 %class = or i1 %cmpzero, %cmpinf20 ret i1 %class21}22 23; Base pattern x == 0.0 || !isfinite(x)24define i1 @not_isfinite_or_zero_f16_commute_or(half %x) {25; CHECK-LABEL: @not_isfinite_or_zero_f16_commute_or(26; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 615)27; CHECK-NEXT: ret i1 [[CLASS]]28;29 %fabs = call half @llvm.fabs.f16(half %x)30 %cmpinf = fcmp ueq half %fabs, 0xH7C0031 %cmpzero = fcmp oeq half %x, 0xH000032 %class = or i1 %cmpinf, %cmpzero33 ret i1 %class34}35 36; Base pattern !isfinite(x) || x == -0.037define i1 @not_isfinite_or_zero_f16_negzero(half %x) {38; CHECK-LABEL: @not_isfinite_or_zero_f16_negzero(39; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 615)40; CHECK-NEXT: ret i1 [[CLASS]]41;42 %fabs = call half @llvm.fabs.f16(half %x)43 %cmpinf = fcmp ueq half %fabs, 0xH7C0044 %cmpzero = fcmp oeq half %x, -0.045 %class = or i1 %cmpzero, %cmpinf46 ret i1 %class47}48 49define i1 @not_isfinite_or_fabs_oeq_zero_f16(half %x) {50; CHECK-LABEL: @not_isfinite_or_fabs_oeq_zero_f16(51; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 615)52; CHECK-NEXT: ret i1 [[CLASS]]53;54 %fabs = call half @llvm.fabs.f16(half %x)55 %cmpinf = fcmp ueq half %fabs, 0xH7C0056 %cmpzero = fcmp oeq half %fabs, 0xH000057 %class = or i1 %cmpzero, %cmpinf58 ret i1 %class59}60 61; Base pattern !isfinite(x) || x == 0.062define <2 x i1> @not_isfinite_or_zero_v2f16(<2 x half> %x) {63; CHECK-LABEL: @not_isfinite_or_zero_v2f16(64; CHECK-NEXT: [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X:%.*]], i32 615)65; CHECK-NEXT: ret <2 x i1> [[CLASS]]66;67 %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)68 %cmpinf = fcmp ueq <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>69 %cmpzero = fcmp oeq <2 x half> %x, zeroinitializer70 %class = or <2 x i1> %cmpzero, %cmpinf71 ret <2 x i1> %class72}73 74; Base pattern !isfinite(x) || x == <0.0, -0.0>75define <2 x i1> @not_isfinite_or_zero_v2f16_pos0_neg0_vec(<2 x half> %x) {76; CHECK-LABEL: @not_isfinite_or_zero_v2f16_pos0_neg0_vec(77; CHECK-NEXT: [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X:%.*]], i32 615)78; CHECK-NEXT: ret <2 x i1> [[CLASS]]79;80 %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)81 %cmpinf = fcmp ueq <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>82 %cmpzero = fcmp oeq <2 x half> %x, <half 0.0, half -0.0>83 %class = or <2 x i1> %cmpzero, %cmpinf84 ret <2 x i1> %class85}86 87; Base pattern x == 0.0 || !isfinite(x)88define <2 x i1> @not_isfinite_or_zero_v2f16_commute_or(<2 x half> %x) {89; CHECK-LABEL: @not_isfinite_or_zero_v2f16_commute_or(90; CHECK-NEXT: [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X:%.*]], i32 615)91; CHECK-NEXT: ret <2 x i1> [[CLASS]]92;93 %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)94 %cmpinf = fcmp ueq <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>95 %cmpzero = fcmp oeq <2 x half> %x, zeroinitializer96 %class = or <2 x i1> %cmpinf, %cmpzero97 ret <2 x i1> %class98}99 100; Positive test101define i1 @oeq_isinf_or_oeq_zero(half %x) {102; CHECK-LABEL: @oeq_isinf_or_oeq_zero(103; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 612)104; CHECK-NEXT: ret i1 [[CLASS]]105;106 %fabs = call half @llvm.fabs.f16(half %x)107 %cmpinf = fcmp oeq half %fabs, 0xH7C00108 %cmpzero = fcmp oeq half %x, 0xH0000109 %class = or i1 %cmpzero, %cmpinf110 ret i1 %class111}112 113; Missing fabs for infinity check114define i1 @ueq_inf_or_oeq_zero(half %x) {115; CHECK-LABEL: @ueq_inf_or_oeq_zero(116; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 611)117; CHECK-NEXT: ret i1 [[CLASS]]118;119 %cmpinf = fcmp ueq half %x, 0xH7C00120 %cmpzero = fcmp oeq half %x, 0xH0000121 %class = or i1 %cmpzero, %cmpinf122 ret i1 %class123}124 125; Extra fabs.126define i1 @oeq_isinf_or_fabs_oeq_zero(half %x) {127; CHECK-LABEL: @oeq_isinf_or_fabs_oeq_zero(128; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 612)129; CHECK-NEXT: ret i1 [[CLASS]]130;131 %fabs = call half @llvm.fabs.f16(half %x)132 %cmpinf = fcmp oeq half %fabs, 0xH7C00133 %cmpzero = fcmp oeq half %fabs, 0xH0000134 %class = or i1 %cmpzero, %cmpinf135 ret i1 %class136}137 138; Positive test139define i1 @ueq_0_or_oeq_inf(half %x) {140; CHECK-LABEL: @ueq_0_or_oeq_inf(141; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 611)142; CHECK-NEXT: ret i1 [[CLASS]]143;144 %fabs = call half @llvm.fabs.f16(half %x)145 %cmpinf = fcmp ueq half %fabs, 0xH0000146 %cmpzero = fcmp oeq half %x, 0xH7C00147 %class = or i1 %cmpzero, %cmpinf148 ret i1 %class149}150 151; Positive test152define i1 @not_isfinite_or_zero_f16_not_inf(half %x) {153; CHECK-LABEL: @not_isfinite_or_zero_f16_not_inf(154; CHECK-NEXT: ret i1 true155;156 %fabs = call half @llvm.fabs.f16(half %x)157 %cmpinf = fcmp ueq half %fabs, 0xH7C01158 %cmpzero = fcmp oeq half %x, 0xH0000159 %class = or i1 %cmpzero, %cmpinf160 ret i1 %class161}162 163; Positive test164define i1 @ueq_inf_or_ueq_zero(half %x) {165; CHECK-LABEL: @ueq_inf_or_ueq_zero(166; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 615)167; CHECK-NEXT: ret i1 [[CLASS]]168;169 %fabs = call half @llvm.fabs.f16(half %x)170 %cmpinf = fcmp ueq half %fabs, 0xH7C00171 %cmpzero = fcmp ueq half %x, 0xH0000172 %class = or i1 %cmpzero, %cmpinf173 ret i1 %class174}175 176; Positive test177define i1 @not_isfinite_and_zero_f16(half %x) {178; CHECK-LABEL: @not_isfinite_and_zero_f16(179; CHECK-NEXT: ret i1 false180;181 %fabs = call half @llvm.fabs.f16(half %x)182 %cmpinf = fcmp ueq half %fabs, 0xH7C00183 %cmpzero = fcmp oeq half %x, 0xH0000184 %class = and i1 %cmpzero, %cmpinf185 ret i1 %class186}187 188; Negative test189define i1 @not_isfinite_or_zero_f16_multi_use_cmp0(half %x, ptr %ptr) {190; CHECK-LABEL: @not_isfinite_or_zero_f16_multi_use_cmp0(191; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])192; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00193; CHECK-NEXT: store i1 [[CMPINF]], ptr [[PTR:%.*]], align 1194; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH0000195; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]]196; CHECK-NEXT: ret i1 [[CLASS]]197;198 %fabs = call half @llvm.fabs.f16(half %x)199 %cmpinf = fcmp ueq half %fabs, 0xH7C00200 store i1 %cmpinf, ptr %ptr201 %cmpzero = fcmp oeq half %x, 0xH0000202 %class = or i1 %cmpzero, %cmpinf203 ret i1 %class204}205 206; Negative test207define i1 @not_isfinite_or_zero_f16_multi_use_cmp1(half %x, ptr %ptr) {208; CHECK-LABEL: @not_isfinite_or_zero_f16_multi_use_cmp1(209; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])210; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00211; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH0000212; CHECK-NEXT: store i1 [[CMPZERO]], ptr [[PTR:%.*]], align 1213; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]]214; CHECK-NEXT: ret i1 [[CLASS]]215;216 %fabs = call half @llvm.fabs.f16(half %x)217 %cmpinf = fcmp ueq half %fabs, 0xH7C00218 %cmpzero = fcmp oeq half %x, 0xH0000219 store i1 %cmpzero, ptr %ptr220 %class = or i1 %cmpzero, %cmpinf221 ret i1 %class222}223 224; Negative test225define i1 @not_isfinite_or_zero_f16_neg_inf(half %x) {226; CHECK-LABEL: @not_isfinite_or_zero_f16_neg_inf(227; CHECK-NEXT: [[CLASS:%.*]] = fcmp ueq half [[X:%.*]], 0xH0000228; CHECK-NEXT: ret i1 [[CLASS]]229;230 %fabs = call half @llvm.fabs.f16(half %x)231 %cmpinf = fcmp ueq half %fabs, 0xHFC00232 %cmpzero = fcmp oeq half %x, 0xH0000233 %class = or i1 %cmpzero, %cmpinf234 ret i1 %class235}236 237; Negative test238define i1 @olt_0_or_fabs_ueq_inf(half %x) {239; CHECK-LABEL: @olt_0_or_fabs_ueq_inf(240; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 543)241; CHECK-NEXT: ret i1 [[CLASS]]242;243 %fabs = call half @llvm.fabs.f16(half %x)244 %cmpinf = fcmp ueq half %fabs, 0xH7C00245 %cmpzero = fcmp olt half %x, 0xH0000246 %class = or i1 %cmpzero, %cmpinf247 ret i1 %class248}249 250; Negative test251define i1 @oeq_0_or_fabs_ult_inf(half %x) {252; CHECK-LABEL: @oeq_0_or_fabs_ult_inf(253; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])254; CHECK-NEXT: [[CLASS:%.*]] = fcmp une half [[TMP1]], 0xH7C00255; CHECK-NEXT: ret i1 [[CLASS]]256;257 %fabs = call half @llvm.fabs.f16(half %x)258 %cmpinf = fcmp ult half %fabs, 0xH7C00259 %cmpzero = fcmp oeq half %x, 0xH0000260 %class = or i1 %cmpzero, %cmpinf261 ret i1 %class262}263 264; Negative test265define i1 @not_isfinite_or_zero_f16_multi_not_0(half %x, ptr %ptr) {266; CHECK-LABEL: @not_isfinite_or_zero_f16_multi_not_0(267; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])268; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00269; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH3C00270; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]]271; CHECK-NEXT: ret i1 [[CLASS]]272;273 %fabs = call half @llvm.fabs.f16(half %x)274 %cmpinf = fcmp ueq half %fabs, 0xH7C00275 %cmpzero = fcmp oeq half %x, 1.0276 %class = or i1 %cmpzero, %cmpinf277 ret i1 %class278}279 280; Negative test281define i1 @not_isfinite_or_zero_f16_fabs_wrong_val(half %x, half %y) {282; CHECK-LABEL: @not_isfinite_or_zero_f16_fabs_wrong_val(283; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[Y:%.*]])284; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00285; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq half [[X:%.*]], 0xH0000286; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]]287; CHECK-NEXT: ret i1 [[CLASS]]288;289 %fabs = call half @llvm.fabs.f16(half %y)290 %cmpinf = fcmp ueq half %fabs, 0xH7C00291 %cmpzero = fcmp oeq half %x, 0xH0000292 %class = or i1 %cmpzero, %cmpinf293 ret i1 %class294}295 296; Negative test297define i1 @not_isfinite_or_zero_f16_not_fabs(half %x) {298; CHECK-LABEL: @not_isfinite_or_zero_f16_not_fabs(299; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.canonicalize.f16(half [[X:%.*]])300; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C00301; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH0000302; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]]303; CHECK-NEXT: ret i1 [[CLASS]]304;305 %fabs = call half @llvm.canonicalize.f16(half %x)306 %cmpinf = fcmp ueq half %fabs, 0xH7C00307 %cmpzero = fcmp oeq half %x, 0xH0000308 %class = or i1 %cmpzero, %cmpinf309 ret i1 %class310}311 312; --------------------------------------------------------------------313; Negated pattern, isfinite(x) && !(x == 0.0)314; --------------------------------------------------------------------315 316; Negation of base pattern, isfinite(x) && !(x == 0.0)317define i1 @negated_isfinite_or_zero_f16(half %x) {318; CHECK-LABEL: @negated_isfinite_or_zero_f16(319; CHECK-NEXT: [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 408)320; CHECK-NEXT: ret i1 [[NOT_CLASS]]321;322 %fabs = call half @llvm.fabs.f16(half %x)323 %cmpinf = fcmp one half %fabs, 0xH7C00324 %cmpzero = fcmp une half %x, 0xH0000325 %not.class = and i1 %cmpzero, %cmpinf326 ret i1 %not.class327}328 329; Commuted !(x == 0.0) && isfinite(x)330define i1 @negated_isfinite_or_zero_f16_commute_and(half %x) {331; CHECK-LABEL: @negated_isfinite_or_zero_f16_commute_and(332; CHECK-NEXT: [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 408)333; CHECK-NEXT: ret i1 [[NOT_CLASS]]334;335 %fabs = call half @llvm.fabs.f16(half %x)336 %cmpinf = fcmp one half %fabs, 0xH7C00337 %cmpzero = fcmp une half %x, 0xH0000338 %not.class = and i1 %cmpinf, %cmpzero339 ret i1 %not.class340}341 342; isfinite(x) && !(x == -0.0)343define i1 @negated_isfinite_or_zero_f16_negzero(half %x) {344; CHECK-LABEL: @negated_isfinite_or_zero_f16_negzero(345; CHECK-NEXT: [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 408)346; CHECK-NEXT: ret i1 [[NOT_CLASS]]347;348 %fabs = call half @llvm.fabs.f16(half %x)349 %cmpinf = fcmp one half %fabs, 0xH7C00350 %cmpzero = fcmp une half %x, -0.0351 %not.class = and i1 %cmpzero, %cmpinf352 ret i1 %not.class353}354 355; Negated pattern356define <2 x i1> @negated_isfinite_or_zero_v2f16(<2 x half> %x) {357; CHECK-LABEL: @negated_isfinite_or_zero_v2f16(358; CHECK-NEXT: [[NOT_CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X:%.*]], i32 408)359; CHECK-NEXT: ret <2 x i1> [[NOT_CLASS]]360;361 %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)362 %cmpinf = fcmp one <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>363 %cmpzero = fcmp une <2 x half> %x, zeroinitializer364 %not.class = and <2 x i1> %cmpzero, %cmpinf365 ret <2 x i1> %not.class366}367 368; Negated pattern, commuted vector and369define <2 x i1> @negated_isfinite_or_zero_v2f16_comumte(<2 x half> %x) {370; CHECK-LABEL: @negated_isfinite_or_zero_v2f16_comumte(371; CHECK-NEXT: [[NOT_CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X:%.*]], i32 408)372; CHECK-NEXT: ret <2 x i1> [[NOT_CLASS]]373;374 %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)375 %cmpinf = fcmp one <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>376 %cmpzero = fcmp une <2 x half> %x, zeroinitializer377 %not.class = and <2 x i1> %cmpinf, %cmpzero378 ret <2 x i1> %not.class379}380 381; Positive test382define i1 @negated_isfinite_or_zero_f16_not_une_zero(half %x) {383; CHECK-LABEL: @negated_isfinite_or_zero_f16_not_une_zero(384; CHECK-NEXT: [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 408)385; CHECK-NEXT: ret i1 [[NOT_CLASS]]386;387 %fabs = call half @llvm.fabs.f16(half %x)388 %cmpinf = fcmp one half %fabs, 0xH7C00389 %cmpzero = fcmp one half %x, 0xH0000390 %not.class = and i1 %cmpzero, %cmpinf391 ret i1 %not.class392}393 394; Positive test395define i1 @negated_isfinite_and_zero_f16(half %x) {396; CHECK-LABEL: @negated_isfinite_and_zero_f16(397; CHECK-NEXT: ret i1 true398;399 %fabs = call half @llvm.fabs.f16(half %x)400 %cmpinf = fcmp one half %fabs, 0xH7C00401 %cmpzero = fcmp une half %x, 0xH0000402 %not.class = or i1 %cmpzero, %cmpinf403 ret i1 %not.class404}405 406; Negative test407define i1 @negated_isfinite_or_zero_f16_swapped_constants(half %x) {408; CHECK-LABEL: @negated_isfinite_or_zero_f16_swapped_constants(409; CHECK-NEXT: [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 412)410; CHECK-NEXT: ret i1 [[NOT_CLASS]]411;412 %fabs = call half @llvm.fabs.f16(half %x)413 %cmpzero = fcmp one half %fabs, 0xH0000414 %cmpinf = fcmp une half %x, 0xH7C00415 %not.class = and i1 %cmpzero, %cmpinf416 ret i1 %not.class417}418 419; Negative test420define i1 @negated_isfinite_or_zero_f16_multi_use_cmp0(half %x, ptr %ptr) {421; CHECK-LABEL: @negated_isfinite_or_zero_f16_multi_use_cmp0(422; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])423; CHECK-NEXT: [[CMPINF:%.*]] = fcmp one half [[FABS]], 0xH7C00424; CHECK-NEXT: store i1 [[CMPINF]], ptr [[PTR:%.*]], align 1425; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp une half [[X]], 0xH0000426; CHECK-NEXT: [[NOT_CLASS:%.*]] = and i1 [[CMPZERO]], [[CMPINF]]427; CHECK-NEXT: ret i1 [[NOT_CLASS]]428;429 %fabs = call half @llvm.fabs.f16(half %x)430 %cmpinf = fcmp one half %fabs, 0xH7C00431 store i1 %cmpinf, ptr %ptr432 %cmpzero = fcmp une half %x, 0xH0000433 %not.class = and i1 %cmpzero, %cmpinf434 ret i1 %not.class435}436 437; Negative test438define i1 @negated_isfinite_or_zero_f16_multi_use_cmp1(half %x, ptr %ptr) {439; CHECK-LABEL: @negated_isfinite_or_zero_f16_multi_use_cmp1(440; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])441; CHECK-NEXT: [[CMPINF:%.*]] = fcmp one half [[FABS]], 0xH7C00442; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp une half [[X]], 0xH0000443; CHECK-NEXT: store i1 [[CMPZERO]], ptr [[PTR:%.*]], align 1444; CHECK-NEXT: [[NOT_CLASS:%.*]] = and i1 [[CMPZERO]], [[CMPINF]]445; CHECK-NEXT: ret i1 [[NOT_CLASS]]446;447 %fabs = call half @llvm.fabs.f16(half %x)448 %cmpinf = fcmp one half %fabs, 0xH7C00449 %cmpzero = fcmp une half %x, 0xH0000450 store i1 %cmpzero, ptr %ptr451 %not.class = and i1 %cmpzero, %cmpinf452 ret i1 %not.class453}454 455; Negative test456define i1 @negated_isfinite_or_zero_f16_multi_use_cmp0_not_one_inf(half %x) {457; CHECK-LABEL: @negated_isfinite_or_zero_f16_multi_use_cmp0_not_one_inf(458; CHECK-NEXT: [[NOT_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 411)459; CHECK-NEXT: ret i1 [[NOT_CLASS]]460;461 %fabs = call half @llvm.fabs.f16(half %x)462 %cmpinf = fcmp une half %fabs, 0xH7C00463 %cmpzero = fcmp une half %x, 0xH0000464 %not.class = and i1 %cmpzero, %cmpinf465 ret i1 %not.class466}467 468; Negative test469define i1 @negated_isfinite_or_zero_f16_fabs_wrong_value(half %x, half %y) {470; CHECK-LABEL: @negated_isfinite_or_zero_f16_fabs_wrong_value(471; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[Y:%.*]])472; CHECK-NEXT: [[CMPINF:%.*]] = fcmp one half [[FABS]], 0xH7C00473; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp une half [[X:%.*]], 0xH0000474; CHECK-NEXT: [[NOT_CLASS:%.*]] = and i1 [[CMPZERO]], [[CMPINF]]475; CHECK-NEXT: ret i1 [[NOT_CLASS]]476;477 %fabs = call half @llvm.fabs.f16(half %y)478 %cmpinf = fcmp one half %fabs, 0xH7C00479 %cmpzero = fcmp une half %x, 0xH0000480 %not.class = and i1 %cmpzero, %cmpinf481 ret i1 %not.class482}483 484; --------------------------------------------------------------------485; Other fcmp to class recognition486; --------------------------------------------------------------------487 488define i1 @fcmp_une_0_or_fcmp_une_inf(half %x) {489; CHECK-LABEL: @fcmp_une_0_or_fcmp_une_inf(490; CHECK-NEXT: ret i1 true491;492 %cmpzero = fcmp une half %x, 0.0493 %cmpinf = fcmp une half %x, 0xH7C00494 %or = or i1 %cmpzero, %cmpinf495 ret i1 %or496}497 498define i1 @fcmp_one_0_and_fcmp_une_fabs_inf(half %x) {499; CHECK-LABEL: @fcmp_one_0_and_fcmp_une_fabs_inf(500; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 408)501; CHECK-NEXT: ret i1 [[AND]]502;503 %fabs = call half @llvm.fabs.f16(half %x)504 %cmpzero = fcmp one half %x, 0.0505 %cmpinf = fcmp une half %fabs, 0xH7C00506 %and = and i1 %cmpzero, %cmpinf507 ret i1 %and508}509 510define i1 @fcmp_une_0_and_fcmp_une_fabs_inf(half %x) {511; CHECK-LABEL: @fcmp_une_0_and_fcmp_une_fabs_inf(512; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 411)513; CHECK-NEXT: ret i1 [[AND]]514;515 %fabs = call half @llvm.fabs.f16(half %x)516 %cmpzero = fcmp une half %x, 0.0517 %cmpinf = fcmp une half %fabs, 0xH7C00518 %and = and i1 %cmpzero, %cmpinf519 ret i1 %and520}521 522define i1 @fcmp_une_0_and_fcmp_une_neginf(half %x) {523; CHECK-LABEL: @fcmp_une_0_and_fcmp_une_neginf(524; CHECK-NEXT: ret i1 true525;526 %cmpzero = fcmp une half %x, 0.0527 %cmpinf = fcmp une half %x, 0xHFC00528 %or = or i1 %cmpzero, %cmpinf529 ret i1 %or530}531 532define i1 @issubnormal_or_inf(half %x) {533; CHECK-LABEL: @issubnormal_or_inf(534; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 756)535; CHECK-NEXT: ret i1 [[CLASS]]536;537 %fabs = call half @llvm.fabs.f16(half %x)538 %cmpinf = fcmp oeq half %fabs, 0xH7C00539 %cmp.smallest.normal = fcmp olt half %fabs, 0xH0400540 %class = or i1 %cmp.smallest.normal, %cmpinf541 ret i1 %class542}543 544define i1 @olt_smallest_normal_or_inf(half %x) {545; CHECK-LABEL: @olt_smallest_normal_or_inf(546; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 764)547; CHECK-NEXT: ret i1 [[CLASS]]548;549 %fabs = call half @llvm.fabs.f16(half %x)550 %cmpinf = fcmp oeq half %fabs, 0xH7C00551 %cmp.smallest.normal = fcmp olt half %x, 0xH0400 ; missing fabs552 %class = or i1 %cmp.smallest.normal, %cmpinf553 ret i1 %class554}555 556define i1 @not_issubnormal_or_inf(half %x) {557; CHECK-LABEL: @not_issubnormal_or_inf(558; CHECK-NEXT: [[NOT:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 267)559; CHECK-NEXT: ret i1 [[NOT]]560;561 %fabs = call half @llvm.fabs.f16(half %x)562 %cmpinf = fcmp une half %fabs, 0xH7C00563 %cmp.smallest.normal = fcmp uge half %fabs, 0xH0400564 %not = and i1 %cmp.smallest.normal, %cmpinf565 ret i1 %not566}567 568define i1 @issubnormal_uge_or_inf(half %x) {569; CHECK-LABEL: @issubnormal_uge_or_inf(570; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 783)571; CHECK-NEXT: ret i1 [[CLASS]]572;573 %fabs = call half @llvm.fabs.f16(half %x)574 %cmpinf = fcmp oeq half %fabs, 0xH7C00575 %cmp.smallest.normal = fcmp uge half %fabs, 0xH0400576 %class = or i1 %cmp.smallest.normal, %cmpinf577 ret i1 %class578}579 580; Negative test, not smallest normal581define i1 @issubnormal_or_inf_wrong_val(half %x) {582; CHECK-LABEL: @issubnormal_or_inf_wrong_val(583; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])584; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[FABS]], 0xH7C00585; CHECK-NEXT: [[CMP_SMALLEST_NORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0401586; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_SMALLEST_NORMAL]], [[CMPINF]]587; CHECK-NEXT: ret i1 [[CLASS]]588;589 %fabs = call half @llvm.fabs.f16(half %x)590 %cmpinf = fcmp oeq half %fabs, 0xH7C00591 %cmp.smallest.normal = fcmp olt half %fabs, 0xH0401592 %class = or i1 %cmp.smallest.normal, %cmpinf593 ret i1 %class594}595 596define i1 @issubnormal_or_inf_neg_smallest_normal(half %x) {597; CHECK-LABEL: @issubnormal_or_inf_neg_smallest_normal(598; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])599; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[FABS]], 0xH7C00600; CHECK-NEXT: ret i1 [[CMPINF]]601;602 %fabs = call half @llvm.fabs.f16(half %x)603 %cmpinf = fcmp oeq half %fabs, 0xH7C00604 %cmp.smallest.normal = fcmp olt half %fabs, 0xH8400605 %class = or i1 %cmp.smallest.normal, %cmpinf606 ret i1 %class607}608 609define i1 @fneg_fabs_olt_neg_smallest_normal_or_inf(half %x) {610; CHECK-LABEL: @fneg_fabs_olt_neg_smallest_normal_or_inf(611; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])612; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[FABS]], 0xH7C00613; CHECK-NEXT: [[CMP_SMALLEST_NORMAL:%.*]] = fcmp ogt half [[FABS]], 0xH0400614; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_SMALLEST_NORMAL]], [[CMPINF]]615; CHECK-NEXT: ret i1 [[CLASS]]616;617 %fabs = call half @llvm.fabs.f16(half %x)618 %cmpinf = fcmp oeq half %fabs, 0xH7C00619 %fneg.fabs = fneg half %fabs620 %cmp.smallest.normal = fcmp olt half %fneg.fabs, 0xH8400621 %class = or i1 %cmp.smallest.normal, %cmpinf622 ret i1 %class623}624 625define i1 @issubnormal_or_finite_olt(half %x) {626; CHECK-LABEL: @issubnormal_or_finite_olt(627; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])628; CHECK-NEXT: [[OR:%.*]] = fcmp one half [[TMP1]], 0xH7C00629; CHECK-NEXT: ret i1 [[OR]]630;631 %fabs = call half @llvm.fabs.f16(half %x)632 %cmpinf = fcmp olt half %fabs, 0xH7C00633 %cmp.smallest.normal = fcmp olt half %fabs, 0xH0400634 %or = or i1 %cmp.smallest.normal, %cmpinf635 ret i1 %or636}637 638; inf | nan | zero | subnormal639define i1 @issubnormal_or_finite_uge(half %x) {640; CHECK-LABEL: @issubnormal_or_finite_uge(641; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 759)642; CHECK-NEXT: ret i1 [[OR]]643;644 %fabs = call half @llvm.fabs.f16(half %x)645 %cmpinf = fcmp uge half %fabs, 0xH7C00646 %cmp.smallest.normal = fcmp olt half %fabs, 0xH0400647 %or = or i1 %cmp.smallest.normal, %cmpinf648 ret i1 %or649}650 651define i1 @issubnormal_and_finite_olt(half %x) {652; CHECK-LABEL: @issubnormal_and_finite_olt(653; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240)654; CHECK-NEXT: ret i1 [[AND]]655;656 %fabs = call half @llvm.fabs.f16(half %x)657 %cmpinf = fcmp olt half %fabs, 0xH7C00658 %cmp.smallest.normal = fcmp olt half %fabs, 0xH0400659 %and = and i1 %cmp.smallest.normal, %cmpinf660 ret i1 %and661}662 663define i1 @not_zero_and_subnormal(half %x) {664; CHECK-LABEL: @not_zero_and_subnormal(665; CHECK-NEXT: [[OR:%.*]] = fcmp ord half [[X:%.*]], 0xH0000666; CHECK-NEXT: ret i1 [[OR]]667;668 %fabs = call half @llvm.fabs.f16(half %x)669 %cmp.zero = fcmp one half %fabs, 0.0670 %cmp.smallest.normal = fcmp olt half %fabs, 0xH0400671 %or = or i1 %cmp.smallest.normal, %cmp.zero672 ret i1 %or673}674 675define i1 @fcmp_fabs_uge_inf_or_fabs_uge_smallest_norm(half %x) {676; CHECK-LABEL: @fcmp_fabs_uge_inf_or_fabs_uge_smallest_norm(677; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 783)678; CHECK-NEXT: ret i1 [[OR]]679;680 %fabs = call half @llvm.fabs.f16(half %x)681 %cmpinf = fcmp uge half %fabs, 0xH7C00682 %cmp.smallest.normal = fcmp uge half %fabs, 0xH0400683 %or = or i1 %cmp.smallest.normal, %cmpinf684 ret i1 %or685}686 687; --------------------------------------------------------------------688; Test ord/uno689; --------------------------------------------------------------------690 691define i1 @is_finite_and_ord(half %x) {692; CHECK-LABEL: @is_finite_and_ord(693; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])694; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[FABS]], 0xH7C00695; CHECK-NEXT: ret i1 [[AND]]696;697 %fabs = call half @llvm.fabs.f16(half %x)698 %is.finite = fcmp ueq half %fabs, 0xH7C00699 %ord = fcmp ord half %x, %x700 %and = and i1 %ord, %is.finite701 ret i1 %and702}703 704define i1 @is_finite_and_uno(half %x) {705; CHECK-LABEL: @is_finite_and_uno(706; CHECK-NEXT: [[AND:%.*]] = fcmp uno half [[X:%.*]], 0xH0000707; CHECK-NEXT: ret i1 [[AND]]708;709 %fabs = call half @llvm.fabs.f16(half %x)710 %is.finite = fcmp ueq half %fabs, 0xH7C00711 %uno = fcmp uno half %x, %x712 %and = and i1 %uno, %is.finite713 ret i1 %and714}715 716define i1 @is_finite_or_ord(half %x) {717; CHECK-LABEL: @is_finite_or_ord(718; CHECK-NEXT: ret i1 true719;720 %fabs = call half @llvm.fabs.f16(half %x)721 %is.finite = fcmp ueq half %fabs, 0xH7C00722 %ord = fcmp ord half %x, %x723 %or = or i1 %ord, %is.finite724 ret i1 %or725}726 727define i1 @is_finite_or_uno(half %x) {728; CHECK-LABEL: @is_finite_or_uno(729; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])730; CHECK-NEXT: [[OR:%.*]] = fcmp ueq half [[TMP1]], 0xH7C00731; CHECK-NEXT: ret i1 [[OR]]732;733 %fabs = call half @llvm.fabs.f16(half %x)734 %is.finite = fcmp ueq half %fabs, 0xH7C00735 %uno = fcmp uno half %x, %x736 %or = or i1 %uno, %is.finite737 ret i1 %or738}739 740define i1 @oeq_isinf_or_uno(half %x) {741; CHECK-LABEL: @oeq_isinf_or_uno(742; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])743; CHECK-NEXT: [[CLASS:%.*]] = fcmp ueq half [[TMP1]], 0xH7C00744; CHECK-NEXT: ret i1 [[CLASS]]745;746 %fabs = call half @llvm.fabs.f16(half %x)747 %cmpinf = fcmp oeq half %fabs, 0xH7C00748 %uno = fcmp uno half %x, 0xH0000749 %class = or i1 %cmpinf, %uno750 ret i1 %class751}752 753define i1 @oeq_isinf_or_ord(half %x) {754; CHECK-LABEL: @oeq_isinf_or_ord(755; CHECK-NEXT: [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH0000756; CHECK-NEXT: ret i1 [[CLASS]]757;758 %fabs = call half @llvm.fabs.f16(half %x)759 %cmpinf = fcmp oeq half %fabs, 0xH7C00760 %uno = fcmp ord half %x, 0xH0000761 %class = or i1 %cmpinf, %uno762 ret i1 %class763}764 765define i1 @oeq_isinf_and_uno(half %x) {766; CHECK-LABEL: @oeq_isinf_and_uno(767; CHECK-NEXT: ret i1 false768;769 %fabs = call half @llvm.fabs.f16(half %x)770 %cmpinf = fcmp oeq half %fabs, 0xH7C00771 %uno = fcmp uno half %x, 0xH0000772 %and = and i1 %cmpinf, %uno773 ret i1 %and774}775 776define i1 @oeq_isinf_and_ord(half %x) {777; CHECK-LABEL: @oeq_isinf_and_ord(778; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])779; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[TMP1]], 0xH7C00780; CHECK-NEXT: ret i1 [[AND]]781;782 %fabs = call half @llvm.fabs.f16(half %x)783 %cmpinf = fcmp oeq half %fabs, 0xH7C00784 %uno = fcmp ord half %x, 0xH0000785 %and = and i1 %cmpinf, %uno786 ret i1 %and787}788 789; --------------------------------------------------------------------790; isnormal(x) || x == 0.0791; --------------------------------------------------------------------792 793define i1 @isnormal_or_zero(half %x) #0 {794; CHECK-LABEL: @isnormal_or_zero(795; CHECK-NEXT: entry:796; CHECK-NEXT: [[AND1:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 360)797; CHECK-NEXT: ret i1 [[AND1]]798;799entry:800 %iseq = fcmp ord half %x, 0xH0000801 %fabs = tail call half @llvm.fabs.f16(half %x)802 %isinf = fcmp ult half %fabs, 0xH7C00803 %isnormal = fcmp uge half %fabs, 0xH0400804 %and = and i1 %iseq, %isinf805 %and1 = and i1 %isnormal, %and806 %cmp = fcmp oeq half %x, 0xH0000807 %spec.select = or i1 %cmp, %and1808 ret i1 %spec.select809}810 811define i1 @isnormal_uge_or_zero_oeq(half %x) #0 {812; CHECK-LABEL: @isnormal_uge_or_zero_oeq(813; CHECK-NEXT: entry:814; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 879)815; CHECK-NEXT: ret i1 [[OR]]816;817entry:818 %fabs = tail call half @llvm.fabs.f16(half %x)819 %is.normal = fcmp uge half %fabs, 0xH0400820 %is.zero = fcmp oeq half %x, 0xH0000821 %or = or i1 %is.normal, %is.zero822 ret i1 %or823}824 825; --------------------------------------------------------------------826; smallest_normal check part of isnormal(x)827; --------------------------------------------------------------------828 829; -> ord830define i1 @isnormalinf_or_ord(half %x) #0 {831; CHECK-LABEL: @isnormalinf_or_ord(832; CHECK-NEXT: [[OR:%.*]] = fcmp ord half [[X:%.*]], 0xH0000833; CHECK-NEXT: ret i1 [[OR]]834;835 %fabs = call half @llvm.fabs.f16(half %x)836 %is.normal.inf = fcmp oge half %fabs, 0xH0400837 %is.ord = fcmp ord half %x, 0xH0000838 %or = or i1 %is.normal.inf, %is.ord839 ret i1 %or840}841 842; -> ord843define i1 @ord_or_isnormalinf(half %x) #0 {844; CHECK-LABEL: @ord_or_isnormalinf(845; CHECK-NEXT: [[OR:%.*]] = fcmp ord half [[X:%.*]], 0xH0000846; CHECK-NEXT: ret i1 [[OR]]847;848 %fabs = call half @llvm.fabs.f16(half %x)849 %is.normal.inf = fcmp oge half %fabs, 0xH0400850 %is.ord = fcmp ord half %x, 0xH0000851 %or = or i1 %is.ord, %is.normal.inf852 ret i1 %or853}854 855; No fabs856; -> iszero857define i1 @une_or_oge_smallest_normal(half %x) #0 {858; CHECK-LABEL: @une_or_oge_smallest_normal(859; CHECK-NEXT: [[OR:%.*]] = fcmp une half [[X:%.*]], 0xH0000860; CHECK-NEXT: ret i1 [[OR]]861;862 %is.normal.inf = fcmp oge half %x, 0xH0400863 %is.une = fcmp une half %x, 0xH0000864 %or = or i1 %is.une, %is.normal.inf865 ret i1 %or866}867 868; -> normal | inf869define i1 @isnormalinf_or_inf(half %x) #0 {870; CHECK-LABEL: @isnormalinf_or_inf(871; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 780)872; CHECK-NEXT: ret i1 [[OR]]873;874 %fabs = call half @llvm.fabs.f16(half %x)875 %is.normal.inf = fcmp oge half %fabs, 0xH0400876 %is.inf = fcmp oeq half %fabs, 0xH7C00877 %or = or i1 %is.normal.inf, %is.inf878 ret i1 %or879}880 881; -> pinf | pnormal882define i1 @posisnormalinf_or_posinf(half %x) #0 {883; CHECK-LABEL: @posisnormalinf_or_posinf(884; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 772)885; CHECK-NEXT: ret i1 [[OR]]886;887 %fabs = call half @llvm.fabs.f16(half %x)888 %is.pos.normal.inf = fcmp oge half %x, 0xH0400889 %is.inf = fcmp oeq half %fabs, 0xH7C00890 %or = or i1 %is.pos.normal.inf, %is.inf891 ret i1 %or892}893 894; -> normal | inf895define i1 @isnormalinf_or_posinf(half %x) #0 {896; CHECK-LABEL: @isnormalinf_or_posinf(897; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 780)898; CHECK-NEXT: ret i1 [[OR]]899;900 %fabs = call half @llvm.fabs.f16(half %x)901 %is.normal.inf = fcmp oge half %fabs, 0xH0400902 %is.pos.inf = fcmp oeq half %x, 0xH7C00903 %or = or i1 %is.normal.inf, %is.pos.inf904 ret i1 %or905}906 907; -> pinf|ninf908define i1 @isnormalinf_and_inf(half %x) #0 {909; CHECK-LABEL: @isnormalinf_and_inf(910; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])911; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[TMP1]], 0xH7C00912; CHECK-NEXT: ret i1 [[AND]]913;914 %fabs = call half @llvm.fabs.f16(half %x)915 %is.normal.inf = fcmp oge half %fabs, 0xH0400916 %is.inf = fcmp oeq half %fabs, 0xH7C00917 %and = and i1 %is.normal.inf, %is.inf918 ret i1 %and919}920 921; -> pinf922define i1 @posisnormalinf_and_posinf(half %x) #0 {923; CHECK-LABEL: @posisnormalinf_and_posinf(924; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00925; CHECK-NEXT: ret i1 [[AND]]926;927 %fabs = call half @llvm.fabs.f16(half %x)928 %is.pos.normal.inf = fcmp oge half %x, 0xH0400929 %is.inf = fcmp oeq half %fabs, 0xH7C00930 %and = and i1 %is.pos.normal.inf, %is.inf931 ret i1 %and932}933 934; -> pinf935define i1 @isnormalinf_and_posinf(half %x) #0 {936; CHECK-LABEL: @isnormalinf_and_posinf(937; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00938; CHECK-NEXT: ret i1 [[AND]]939;940 %fabs = call half @llvm.fabs.f16(half %x)941 %is.normal.inf = fcmp oge half %fabs, 0xH0400942 %is.pos.inf = fcmp oeq half %x, 0xH7C00943 %and = and i1 %is.normal.inf, %is.pos.inf944 ret i1 %and945}946 947; --------------------------------------------------------------------948; smallest_normal check part of isnormal(x) with inverted compare949; --------------------------------------------------------------------950 951; -> true952define i1 @not_isnormalinf_or_ord(half %x) #0 {953; CHECK-LABEL: @not_isnormalinf_or_ord(954; CHECK-NEXT: ret i1 true955;956 %fabs = call half @llvm.fabs.f16(half %x)957 %not.is.normal.inf = fcmp ult half %fabs, 0xH0400958 %is.ord = fcmp ord half %x, 0xH0000959 %or = or i1 %not.is.normal.inf, %is.ord960 ret i1 %or961}962 963; -> subnormal | zero964define i1 @not_isnormalinf_and_ord(half %x) #0 {965; CHECK-LABEL: @not_isnormalinf_and_ord(966; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240)967; CHECK-NEXT: ret i1 [[AND]]968;969 %fabs = call half @llvm.fabs.f16(half %x)970 %not.is.normal.inf = fcmp ult half %fabs, 0xH0400971 %is.ord = fcmp ord half %x, 0xH0000972 %and = and i1 %not.is.normal.inf, %is.ord973 ret i1 %and974}975 976; -> ~ninf977define i1 @not_isnormalinf_or_inf(half %x) #0 {978; CHECK-LABEL: @not_isnormalinf_or_inf(979; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])980; CHECK-NEXT: [[OR:%.*]] = fcmp une half [[TMP1]], 0xH7C00981; CHECK-NEXT: ret i1 [[OR]]982;983 %fabs = call half @llvm.fabs.f16(half %x)984 %not.is.normal.inf = fcmp ult half %fabs, 0xH0400985 %is.inf = fcmp olt half %fabs, 0xH7C00986 %or = or i1 %not.is.normal.inf, %is.inf987 ret i1 %or988}989 990; -> subnormal | zero | nan991define i1 @not_isnormalinf_or_uno(half %x) #0 {992; CHECK-LABEL: @not_isnormalinf_or_uno(993; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])994; CHECK-NEXT: [[OR:%.*]] = fcmp ult half [[FABS]], 0xH0400995; CHECK-NEXT: ret i1 [[OR]]996;997 %fabs = call half @llvm.fabs.f16(half %x)998 %not.is.normal.inf = fcmp ult half %fabs, 0xH0400999 %is.uno = fcmp uno half %fabs, 0.01000 %or = or i1 %not.is.normal.inf, %is.uno1001 ret i1 %or1002}1003 1004; -> subnormal | zero | nan1005define i1 @not_isnormalinf_or_uno_nofabs(half %x) #0 {1006; CHECK-LABEL: @not_isnormalinf_or_uno_nofabs(1007; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])1008; CHECK-NEXT: [[OR:%.*]] = fcmp ult half [[FABS]], 0xH04001009; CHECK-NEXT: ret i1 [[OR]]1010;1011 %fabs = call half @llvm.fabs.f16(half %x)1012 %not.is.normal.inf = fcmp ult half %fabs, 0xH04001013 %is.uno = fcmp uno half %x, 0.01014 %or = or i1 %not.is.normal.inf, %is.uno1015 ret i1 %or1016}1017 1018; -> ~pnormal1019define i1 @not_negisnormalinf_or_inf(half %x) #0 {1020; CHECK-LABEL: @not_negisnormalinf_or_inf(1021; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 767)1022; CHECK-NEXT: ret i1 [[OR]]1023;1024 %fabs = call half @llvm.fabs.f16(half %x)1025 %not.is.neg.normal.inf = fcmp ult half %x, 0xH04001026 %is.inf = fcmp oeq half %fabs, 0xH7C001027 %or = or i1 %not.is.neg.normal.inf, %is.inf1028 ret i1 %or1029}1030 1031; -> ~pnormal1032define i1 @not_negisnormalinf_or_posinf(half %x) #0 {1033; CHECK-LABEL: @not_negisnormalinf_or_posinf(1034; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 767)1035; CHECK-NEXT: ret i1 [[OR]]1036;1037 %not.is.pos.normal.inf = fcmp ult half %x, 0xH04001038 %is.inf = fcmp oeq half %x, 0xH7C001039 %or = or i1 %not.is.pos.normal.inf, %is.inf1040 ret i1 %or1041}1042 1043; -> ninf | nnormal1044define i1 @not_isposnormalinf_and_isnormalinf(half %x) #0 {1045; CHECK-LABEL: @not_isposnormalinf_and_isnormalinf(1046; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 12)1047; CHECK-NEXT: ret i1 [[AND]]1048;1049 %not.is.pos.normal.inf = fcmp ult half %x, 0xH04001050 %fabs = call half @llvm.fabs.f16(half %x)1051 %is.normal.inf = fcmp oge half %fabs, 0xH04001052 %and = and i1 %not.is.pos.normal.inf, %is.normal.inf1053 ret i1 %and1054}1055 1056; -> ord1057define i1 @olt_smallest_normal_or_ord(half %x) #0 {1058; CHECK-LABEL: @olt_smallest_normal_or_ord(1059; CHECK-NEXT: [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH00001060; CHECK-NEXT: ret i1 [[CLASS]]1061;1062 %ord = fcmp ord half %x, 0.01063 %cmp.smallest.normal = fcmp olt half %x, 0xH04001064 %class = or i1 %cmp.smallest.normal, %ord1065 ret i1 %class1066}1067 1068; -> ~pinf1069define i1 @olt_smallest_normal_or_uno(half %x) #0 {1070; CHECK-LABEL: @olt_smallest_normal_or_uno(1071; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 255)1072; CHECK-NEXT: ret i1 [[CLASS]]1073;1074 %uno = fcmp uno half %x, 0.01075 %cmp.smallest.normal = fcmp olt half %x, 0xH04001076 %class = or i1 %cmp.smallest.normal, %uno1077 ret i1 %class1078}1079 1080define i1 @olt_smallest_normal_or_finite(half %x) #0 {1081; CHECK-LABEL: @olt_smallest_normal_or_finite(1082; CHECK-NEXT: [[CLASS:%.*]] = fcmp one half [[X:%.*]], 0xH7C001083; CHECK-NEXT: ret i1 [[CLASS]]1084;1085 %fabs = call half @llvm.fabs.f16(half %x)1086 %is.finite = fcmp olt half %fabs, 0xH7C001087 %cmp.smallest.normal = fcmp olt half %x, 0xH04001088 %class = or i1 %cmp.smallest.normal, %is.finite1089 ret i1 %class1090}1091 1092define i1 @uge_smallest_normal_or_ord(half %x) #0 {1093; CHECK-LABEL: @uge_smallest_normal_or_ord(1094; CHECK-NEXT: ret i1 true1095;1096 %ord = fcmp ord half %x, 0.01097 %cmp.smallest.normal = fcmp uge half %x, 0xH04001098 %class = or i1 %cmp.smallest.normal, %ord1099 ret i1 %class1100}1101 1102; -> nan | pnormal | pinf1103define i1 @uge_smallest_normal_or_uno(half %x) #0 {1104; CHECK-LABEL: @uge_smallest_normal_or_uno(1105; CHECK-NEXT: [[CMP_SMALLEST_NORMAL:%.*]] = fcmp uge half [[X:%.*]], 0xH04001106; CHECK-NEXT: ret i1 [[CMP_SMALLEST_NORMAL]]1107;1108 %uno = fcmp uno half %x, 0.01109 %cmp.smallest.normal = fcmp uge half %x, 0xH04001110 %class = or i1 %cmp.smallest.normal, %uno1111 ret i1 %class1112}1113 1114; -> uno1115define i1 @uge_smallest_normal_and_uno(half %x) #0 {1116; CHECK-LABEL: @uge_smallest_normal_and_uno(1117; CHECK-NEXT: [[CLASS:%.*]] = fcmp uno half [[X:%.*]], 0xH00001118; CHECK-NEXT: ret i1 [[CLASS]]1119;1120 %uno = fcmp uno half %x, 0.01121 %cmp.smallest.normal = fcmp uge half %x, 0xH04001122 %class = and i1 %cmp.smallest.normal, %uno1123 ret i1 %class1124}1125 1126; -> true1127define i1 @olt_infinity_or_finite(half %x) #0 {1128; CHECK-LABEL: @olt_infinity_or_finite(1129; CHECK-NEXT: [[CLASS:%.*]] = fcmp one half [[X:%.*]], 0xH7C001130; CHECK-NEXT: ret i1 [[CLASS]]1131;1132 %lt.infinity = fcmp olt half %x, 0xH7C001133 %cmp.smallest.normal = fcmp olt half %x, 0xH04001134 %class = or i1 %cmp.smallest.normal, %lt.infinity1135 ret i1 %class1136}1137 1138; -> zero|subnormal|normal1139define i1 @olt_infinity_and_finite(half %x) #0 { ; bustttedddd1140; CHECK-LABEL: @olt_infinity_and_finite(1141; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 252)1142; CHECK-NEXT: ret i1 [[CLASS]]1143;1144 %lt.infinity = fcmp olt half %x, 0xH7C001145 %cmp.smallest.normal = fcmp olt half %x, 0xH04001146 %class = and i1 %cmp.smallest.normal, %lt.infinity1147 ret i1 %class1148}1149 1150; -> ord1151define i1 @olt_infinity_or_ord(half %x) #0 {1152; CHECK-LABEL: @olt_infinity_or_ord(1153; CHECK-NEXT: [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH00001154; CHECK-NEXT: ret i1 [[CLASS]]1155;1156 %lt.infinity = fcmp olt half %x, 0xH7C001157 %ord = fcmp ord half %x, 0xH04001158 %class = or i1 %lt.infinity, %ord1159 ret i1 %class1160}1161 1162; -> ~posinf1163define i1 @olt_infinity_or_uno(half %x) #0 {1164; CHECK-LABEL: @olt_infinity_or_uno(1165; CHECK-NEXT: [[CLASS:%.*]] = fcmp une half [[X:%.*]], 0xH7C001166; CHECK-NEXT: ret i1 [[CLASS]]1167;1168 %lt.infinity = fcmp olt half %x, 0xH7C001169 %uno = fcmp uno half %x, 0xH04001170 %class = or i1 %lt.infinity, %uno1171 ret i1 %class1172}1173 1174define i1 @olt_infinity_or_subnormal(half %x) #0 {1175; CHECK-LABEL: @olt_infinity_or_subnormal(1176; CHECK-NEXT: [[CLASS:%.*]] = fcmp one half [[X:%.*]], 0xH7C001177; CHECK-NEXT: ret i1 [[CLASS]]1178;1179 %lt.infinity = fcmp olt half %x, 0xH7C001180 %fabs = call half @llvm.fabs.f16(half %x)1181 %is.subnormal = fcmp olt half %fabs, 0xH04001182 %class = or i1 %lt.infinity, %is.subnormal1183 ret i1 %class1184}1185 1186define i1 @olt_infinity_and_subnormal(half %x) #0 {1187; CHECK-LABEL: @olt_infinity_and_subnormal(1188; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240)1189; CHECK-NEXT: ret i1 [[CLASS]]1190;1191 %lt.infinity = fcmp olt half %x, 0xH7C001192 %fabs = call half @llvm.fabs.f16(half %x)1193 %is.subnormal = fcmp olt half %fabs, 0xH04001194 %class = and i1 %lt.infinity, %is.subnormal1195 ret i1 %class1196}1197 1198define i1 @olt_infinity_and_not_subnormal(half %x) #0 {1199; CHECK-LABEL: @olt_infinity_and_not_subnormal(1200; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 268)1201; CHECK-NEXT: ret i1 [[CLASS]]1202;1203 %lt.infinity = fcmp olt half %x, 0xH7C001204 %fabs = call half @llvm.fabs.f16(half %x)1205 %is.subnormal = fcmp olt half %fabs, 0xH04001206 %not.subnormal = xor i1 %is.subnormal, true1207 %class = and i1 %lt.infinity, %not.subnormal1208 ret i1 %class1209}1210 1211; -> ninf1212define i1 @olt_infinity_and_ueq_inf(half %x) #0 {1213; CHECK-LABEL: @olt_infinity_and_ueq_inf(1214; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC001215; CHECK-NEXT: ret i1 [[CLASS]]1216;1217 %lt.infinity = fcmp olt half %x, 0xH7C001218 %fabs = call half @llvm.fabs.f16(half %x)1219 %eq.inf = fcmp ueq half %fabs, 0xH7C001220 %class = and i1 %lt.infinity, %eq.inf1221 ret i1 %class1222}1223 1224; -> true1225define i1 @olt_infinity_or_ueq_inf(half %x) #0 {1226; CHECK-LABEL: @olt_infinity_or_ueq_inf(1227; CHECK-NEXT: ret i1 true1228;1229 %lt.infinity = fcmp olt half %x, 0xH7C001230 %eq.inf = fcmp ueq half %x, 0xH7C001231 %class = or i1 %lt.infinity, %eq.inf1232 ret i1 %class1233}1234 1235; -> pnormal1236define i1 @olt_smallest_normal_or_ueq_inf(half %x) #0 {1237; CHECK-LABEL: @olt_smallest_normal_or_ueq_inf(1238; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 767)1239; CHECK-NEXT: ret i1 [[CLASS]]1240;1241 %lt.normal = fcmp olt half %x, 0xH04001242 %eq.inf = fcmp ueq half %x, 0xH7C001243 %class = or i1 %lt.normal, %eq.inf1244 ret i1 %class1245}1246 1247; -> ~pinf1248define i1 @olt_smallest_normal_or_une_inf(half %x) #0 {1249; CHECK-LABEL: @olt_smallest_normal_or_une_inf(1250; CHECK-NEXT: [[CLASS:%.*]] = fcmp une half [[X:%.*]], 0xH7C001251; CHECK-NEXT: ret i1 [[CLASS]]1252;1253 %lt.normal = fcmp olt half %x, 0xH04001254 %eq.inf = fcmp une half %x, 0xH7C001255 %class = or i1 %lt.normal, %eq.inf1256 ret i1 %class1257}1258 1259; -> ninf | nnormal | subnormal | zero1260define i1 @olt_smallest_normal_and_une_inf(half %x) #0 {1261; CHECK-LABEL: @olt_smallest_normal_and_une_inf(1262; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 252)1263; CHECK-NEXT: ret i1 [[CLASS]]1264;1265 %lt.normal = fcmp olt half %x, 0xH04001266 %eq.inf = fcmp une half %x, 0xH7C001267 %class = and i1 %lt.normal, %eq.inf1268 ret i1 %class1269}1270 1271define i1 @olt_smallest_normal_and_une_inf_or_oeq_smallest_normal(half %x) #0 {1272; CHECK-LABEL: @olt_smallest_normal_and_une_inf_or_oeq_smallest_normal(1273; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 252)1274; CHECK-NEXT: ret i1 [[CLASS]]1275;1276 %lt.normal = fcmp olt half %x, 0xH04001277 %eq.inf = fcmp une half %x, 0xH7C001278 %class = and i1 %lt.normal, %eq.inf1279 %eq.normal = fcmp oeq half %x, 0xH04001280 %eq.largest.normal = or i1 %eq.normal, %class1281 ret i1 %class1282}1283 1284define i1 @olt_smallest_normal_and_une_inf_or_one_smallest_normal(half %x) #0 {1285; CHECK-LABEL: @olt_smallest_normal_and_une_inf_or_one_smallest_normal(1286; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 252)1287; CHECK-NEXT: ret i1 [[CLASS]]1288;1289 %lt.normal = fcmp olt half %x, 0xH04001290 %eq.inf = fcmp une half %x, 0xH7C001291 %class = and i1 %lt.normal, %eq.inf1292 %ne.normal = fcmp one half %x, 0xH04001293 %eq.largest.normal = or i1 %ne.normal, %class1294 ret i1 %class1295}1296 1297define i1 @oge_fabs_eq_inf_and_ord(half %x) #0 {1298; CHECK-LABEL: @oge_fabs_eq_inf_and_ord(1299; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])1300; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[TMP1]], 0xH7C001301; CHECK-NEXT: ret i1 [[AND]]1302;1303 %fabs = call half @llvm.fabs.f16(half %x)1304 %oge.fabs.inf = fcmp oge half %fabs, 0xH7C001305 %ord = fcmp ord half %x, 0xH00001306 %and = and i1 %oge.fabs.inf, %ord1307 ret i1 %and1308}1309 1310define i1 @oge_eq_inf_and_ord(half %x) #0 {1311; CHECK-LABEL: @oge_eq_inf_and_ord(1312; CHECK-NEXT: [[OGE_FABS_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C001313; CHECK-NEXT: ret i1 [[OGE_FABS_INF]]1314;1315 %oge.fabs.inf = fcmp oge half %x, 0xH7C001316 %ord = fcmp ord half %x, 0xH00001317 %and = and i1 %oge.fabs.inf, %ord1318 ret i1 %and1319}1320 1321define i1 @oge_fabs_eq_inf_or_uno(half %x) #0 {1322; CHECK-LABEL: @oge_fabs_eq_inf_or_uno(1323; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])1324; CHECK-NEXT: [[OR:%.*]] = fcmp ueq half [[TMP1]], 0xH7C001325; CHECK-NEXT: ret i1 [[OR]]1326;1327 %fabs = call half @llvm.fabs.f16(half %x)1328 %oge.fabs.inf = fcmp oge half %fabs, 0xH7C001329 %uno = fcmp uno half %x, 0xH00001330 %or = or i1 %oge.fabs.inf, %uno1331 ret i1 %or1332}1333 1334define i1 @oge_eq_inf_or_uno(half %x) #0 {1335; CHECK-LABEL: @oge_eq_inf_or_uno(1336; CHECK-NEXT: [[OR:%.*]] = fcmp ueq half [[X:%.*]], 0xH7C001337; CHECK-NEXT: ret i1 [[OR]]1338;1339 %oge.fabs.inf = fcmp oge half %x, 0xH7C001340 %uno = fcmp uno half %x, 0xH00001341 %or = or i1 %oge.fabs.inf, %uno1342 ret i1 %or1343}1344 1345define i1 @ult_fabs_eq_inf_and_ord(half %x) #0 {1346; CHECK-LABEL: @ult_fabs_eq_inf_and_ord(1347; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])1348; CHECK-NEXT: [[AND:%.*]] = fcmp one half [[FABS]], 0xH7C001349; CHECK-NEXT: ret i1 [[AND]]1350;1351 %fabs = call half @llvm.fabs.f16(half %x)1352 %ult.fabs.inf = fcmp ult half %fabs, 0xH7C001353 %ord = fcmp ord half %x, 0xH00001354 %and = and i1 %ult.fabs.inf, %ord1355 ret i1 %and1356}1357 1358define i1 @ult_eq_inf_and_ord(half %x) #0 {1359; CHECK-LABEL: @ult_eq_inf_and_ord(1360; CHECK-NEXT: [[AND:%.*]] = fcmp one half [[X:%.*]], 0xH7C001361; CHECK-NEXT: ret i1 [[AND]]1362;1363 %ult.fabs.inf = fcmp ult half %x, 0xH7C001364 %ord = fcmp ord half %x, 0xH00001365 %and = and i1 %ult.fabs.inf, %ord1366 ret i1 %and1367}1368 1369define i1 @ult_fabs_eq_inf_or_uno(half %x) #0 {1370; CHECK-LABEL: @ult_fabs_eq_inf_or_uno(1371; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])1372; CHECK-NEXT: [[OR:%.*]] = fcmp une half [[TMP1]], 0xH7C001373; CHECK-NEXT: ret i1 [[OR]]1374;1375 %fabs = call half @llvm.fabs.f16(half %x)1376 %ult.fabs.inf = fcmp ult half %fabs, 0xH7C001377 %uno = fcmp uno half %x, 0xH00001378 %or = or i1 %ult.fabs.inf, %uno1379 ret i1 %or1380}1381 1382define i1 @ult_eq_inf_or_uno(half %x) #0 {1383; CHECK-LABEL: @ult_eq_inf_or_uno(1384; CHECK-NEXT: [[ULT_FABS_INF:%.*]] = fcmp une half [[X:%.*]], 0xH7C001385; CHECK-NEXT: ret i1 [[ULT_FABS_INF]]1386;1387 %ult.fabs.inf = fcmp ult half %x, 0xH7C001388 %uno = fcmp uno half %x, 0xH00001389 %or = or i1 %ult.fabs.inf, %uno1390 ret i1 %or1391}1392 1393 1394; Can't do anything with this1395define i1 @oeq_neginfinity_or_oeq_smallest_normal(half %x) #0 {1396; CHECK-LABEL: @oeq_neginfinity_or_oeq_smallest_normal(1397; CHECK-NEXT: [[OEQ_NEG_INFINITY:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC001398; CHECK-NEXT: [[CMP_SMALLEST_NORMAL:%.*]] = fcmp oeq half [[X]], 0xH04001399; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[OEQ_NEG_INFINITY]], [[CMP_SMALLEST_NORMAL]]1400; CHECK-NEXT: ret i1 [[CLASS]]1401;1402 %oeq.neg.infinity = fcmp oeq half %x, 0xHFC001403 %cmp.smallest.normal = fcmp oeq half %x, 0xH04001404 %class = or i1 %oeq.neg.infinity, %cmp.smallest.normal1405 ret i1 %class1406}1407 1408; -> ninf | fcZero | fcSubnormal1409define i1 @oeq_neginfinity_or_olt_smallest_normal(half %x) #0 {1410; CHECK-LABEL: @oeq_neginfinity_or_olt_smallest_normal(1411; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 252)1412; CHECK-NEXT: ret i1 [[CLASS]]1413;1414 %oeq.neg.infinity = fcmp oeq half %x, 0xHFC001415 %cmp.smallest.normal = fcmp olt half %x, 0xH04001416 %class = or i1 %oeq.neg.infinity, %cmp.smallest.normal1417 ret i1 %class1418}1419 1420; -> ninf1421define i1 @oeq_neginfinity_and_olt_smallest_normal(half %x) #0 {1422; CHECK-LABEL: @oeq_neginfinity_and_olt_smallest_normal(1423; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC001424; CHECK-NEXT: ret i1 [[CLASS]]1425;1426 %oeq.neg.infinity = fcmp oeq half %x, 0xHFC001427 %cmp.smallest.normal = fcmp olt half %x, 0xH04001428 %class = and i1 %oeq.neg.infinity, %cmp.smallest.normal1429 ret i1 %class1430}1431 1432; -> ninf | pnormal | pinf1433define i1 @oeq_neginfinity_or_oge_smallest_normal(half %x) #0 {1434; CHECK-LABEL: @oeq_neginfinity_or_oge_smallest_normal(1435; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 772)1436; CHECK-NEXT: ret i1 [[CLASS]]1437;1438 %oeq.neg.infinity = fcmp oeq half %x, 0xHFC001439 %cmp.smallest.normal = fcmp oge half %x, 0xH04001440 %class = or i1 %oeq.neg.infinity, %cmp.smallest.normal1441 ret i1 %class1442}1443 1444; -> false1445define i1 @oeq_neginfinity_and_oge_smallest_normal(half %x) #0 {1446; CHECK-LABEL: @oeq_neginfinity_and_oge_smallest_normal(1447; CHECK-NEXT: ret i1 false1448;1449 %oeq.neg.infinity = fcmp oeq half %x, 0xHFC001450 %cmp.smallest.normal = fcmp oge half %x, 0xH04001451 %class = and i1 %oeq.neg.infinity, %cmp.smallest.normal1452 ret i1 %class1453}1454 1455; -> ord1456define i1 @oeq_neginfinity_or_ord(half %x) #0 {1457; CHECK-LABEL: @oeq_neginfinity_or_ord(1458; CHECK-NEXT: [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH00001459; CHECK-NEXT: ret i1 [[CLASS]]1460;1461 %oeq.neg.infinity = fcmp oeq half %x, 0xHFC001462 %ord = fcmp ord half %x, 0.01463 %class = or i1 %oeq.neg.infinity, %ord1464 ret i1 %class1465}1466 1467; -> ninf1468define i1 @oeq_neginfinity_and_ord(half %x) #0 {1469; CHECK-LABEL: @oeq_neginfinity_and_ord(1470; CHECK-NEXT: [[OEQ_NEG_INFINITY:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC001471; CHECK-NEXT: ret i1 [[OEQ_NEG_INFINITY]]1472;1473 %oeq.neg.infinity = fcmp oeq half %x, 0xHFC001474 %ord = fcmp ord half %x, 0.01475 %class = and i1 %oeq.neg.infinity, %ord1476 ret i1 %class1477}1478 1479; can't do anything with this1480define i1 @une_neginfinity_or_oeq_smallest_normal(half %x) #0 {1481; CHECK-LABEL: @une_neginfinity_or_oeq_smallest_normal(1482; CHECK-NEXT: [[UNE_NEG_INFINITY:%.*]] = fcmp une half [[X:%.*]], 0xHFC001483; CHECK-NEXT: [[CMP_SMALLEST_NORMAL:%.*]] = fcmp oeq half [[X]], 0xH04001484; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[UNE_NEG_INFINITY]], [[CMP_SMALLEST_NORMAL]]1485; CHECK-NEXT: ret i1 [[CLASS]]1486;1487 %une.neg.infinity = fcmp une half %x, 0xHFC001488 %cmp.smallest.normal = fcmp oeq half %x, 0xH04001489 %class = or i1 %une.neg.infinity, %cmp.smallest.normal1490 ret i1 %class1491}1492 1493; -> true1494define i1 @une_neginfinity_or_ord(half %x) #0 {1495; CHECK-LABEL: @une_neginfinity_or_ord(1496; CHECK-NEXT: ret i1 true1497;1498 %une.neg.infinity = fcmp une half %x, 0xHFC001499 %ord = fcmp ord half %x, 0.01500 %class = or i1 %une.neg.infinity, %ord1501 ret i1 %class1502}1503 1504; -> ~(nan | ninf)1505define i1 @une_neginfinity_and_ord(half %x) #0 {1506; CHECK-LABEL: @une_neginfinity_and_ord(1507; CHECK-NEXT: [[CLASS:%.*]] = fcmp one half [[X:%.*]], 0xHFC001508; CHECK-NEXT: ret i1 [[CLASS]]1509;1510 %une.neg.infinity = fcmp une half %x, 0xHFC001511 %ord = fcmp ord half %x, 0.01512 %class = and i1 %une.neg.infinity, %ord1513 ret i1 %class1514}1515 1516; -> ord1517define i1 @one_neginfinity_or_olt_smallest_normal(half %x) #0 {1518; CHECK-LABEL: @one_neginfinity_or_olt_smallest_normal(1519; CHECK-NEXT: [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH00001520; CHECK-NEXT: ret i1 [[CLASS]]1521;1522 %one.neg.infinity = fcmp one half %x, 0xHFC001523 %cmp.smallest.normal = fcmp olt half %x, 0xH04001524 %class = or i1 %one.neg.infinity, %cmp.smallest.normal1525 ret i1 %class1526}1527 1528; -> ~(nan|ninf)1529define i1 @one_neginfinity_and_olt_smallest_normal(half %x) #0 {1530; CHECK-LABEL: @one_neginfinity_and_olt_smallest_normal(1531; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 248)1532; CHECK-NEXT: ret i1 [[CLASS]]1533;1534 %one.neg.infinity = fcmp one half %x, 0xHFC001535 %cmp.smallest.normal = fcmp olt half %x, 0xH04001536 %class = and i1 %one.neg.infinity, %cmp.smallest.normal1537 ret i1 %class1538}1539 1540; -> ~ninf1541define i1 @one_neginfinity_or_uno(half %x) #0 {1542; CHECK-LABEL: @one_neginfinity_or_uno(1543; CHECK-NEXT: [[CLASS:%.*]] = fcmp une half [[X:%.*]], 0xHFC001544; CHECK-NEXT: ret i1 [[CLASS]]1545;1546 %one.neg.infinity = fcmp one half %x, 0xHFC001547 %uno = fcmp uno half %x, 0.01548 %class = or i1 %one.neg.infinity, %uno1549 ret i1 %class1550}1551 1552; -> ~ninf1553define i1 @one_neginfinity_and_ord(half %x) #0 {1554; CHECK-LABEL: @one_neginfinity_and_ord(1555; CHECK-NEXT: ret i1 false1556;1557 %one.neg.infinity = fcmp one half %x, 0xHFC001558 %ord = fcmp uno half %x, 0.01559 %class = and i1 %one.neg.infinity, %ord1560 ret i1 %class1561}1562 1563; -> pnormal|pinf1564define i1 @one_neginfinity_and_uge_smallest_normal(half %x) #0 {1565; CHECK-LABEL: @one_neginfinity_and_uge_smallest_normal(1566; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 768)1567; CHECK-NEXT: ret i1 [[CLASS]]1568;1569 %one.neg.infinity = fcmp one half %x, 0xHFC001570 %cmp.smallest.normal = fcmp uge half %x, 0xH04001571 %class = and i1 %one.neg.infinity, %cmp.smallest.normal1572 ret i1 %class1573}1574 1575; -> ~(pnormal|pinf)1576define i1 @ueq_neginfinity_or_olt_smallest_normal(half %x) #0 {1577; CHECK-LABEL: @ueq_neginfinity_or_olt_smallest_normal(1578; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 255)1579; CHECK-NEXT: ret i1 [[CLASS]]1580;1581 %ueq.neg.infinity = fcmp ueq half %x, 0xHFC001582 %cmp.smallest.normal = fcmp olt half %x, 0xH04001583 %class = or i1 %ueq.neg.infinity, %cmp.smallest.normal1584 ret i1 %class1585}1586 1587; -> ninf1588define i1 @ueq_neginfinity_and_olt_smallest_normal(half %x) #0 {1589; CHECK-LABEL: @ueq_neginfinity_and_olt_smallest_normal(1590; CHECK-NEXT: [[CLASS:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC001591; CHECK-NEXT: ret i1 [[CLASS]]1592;1593 %ueq.neg.infinity = fcmp ueq half %x, 0xHFC001594 %cmp.smallest.normal = fcmp olt half %x, 0xH04001595 %class = and i1 %ueq.neg.infinity, %cmp.smallest.normal1596 ret i1 %class1597}1598 1599; -> nan|ninf1600define i1 @ueq_neginfinity_or_uno(half %x) #0 {1601; CHECK-LABEL: @ueq_neginfinity_or_uno(1602; CHECK-NEXT: [[UEQ_NEG_INFINITY:%.*]] = fcmp ueq half [[X:%.*]], 0xHFC001603; CHECK-NEXT: ret i1 [[UEQ_NEG_INFINITY]]1604;1605 %ueq.neg.infinity = fcmp ueq half %x, 0xHFC001606 %uno = fcmp uno half %x, 0.01607 %class = or i1 %ueq.neg.infinity, %uno1608 ret i1 %class1609}1610 1611; -> nan|ninf1612define i1 @ueq_neginfinity_and_ord(half %x) #0 {1613; CHECK-LABEL: @ueq_neginfinity_and_ord(1614; CHECK-NEXT: [[CLASS:%.*]] = fcmp uno half [[X:%.*]], 0xH00001615; CHECK-NEXT: ret i1 [[CLASS]]1616;1617 %ueq.neg.infinity = fcmp ueq half %x, 0xHFC001618 %ord = fcmp uno half %x, 0.01619 %class = and i1 %ueq.neg.infinity, %ord1620 ret i1 %class1621}1622 1623; -> uno1624define i1 @ueq_neginfinity_and_uge_smallest_normal(half %x) #0 {1625; CHECK-LABEL: @ueq_neginfinity_and_uge_smallest_normal(1626; CHECK-NEXT: [[CLASS:%.*]] = fcmp uno half [[X:%.*]], 0xH00001627; CHECK-NEXT: ret i1 [[CLASS]]1628;1629 %ueq.neg.infinity = fcmp ueq half %x, 0xHFC001630 %cmp.smallest.normal = fcmp uge half %x, 0xH04001631 %class = and i1 %ueq.neg.infinity, %cmp.smallest.normal1632 ret i1 %class1633}1634 1635; -> ord1636define i1 @fabs_oeq_neginfinity_or_ord(half %x) #0 {1637; CHECK-LABEL: @fabs_oeq_neginfinity_or_ord(1638; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH00001639; CHECK-NEXT: ret i1 [[ORD]]1640;1641 %fabs = call half @llvm.fabs.f16(half %x)1642 %fabs.oeq.neg.infinity = fcmp oeq half %fabs, 0xHFC001643 %ord = fcmp ord half %x, 0.01644 %class = or i1 %fabs.oeq.neg.infinity, %ord1645 ret i1 %class1646}1647 1648; -> true1649define i1 @fabs_une_neginfinity_or_ord(half %x) #0 {1650; CHECK-LABEL: @fabs_une_neginfinity_or_ord(1651; CHECK-NEXT: ret i1 true1652;1653 %fabs = call half @llvm.fabs.f16(half %x)1654 %fabs.une.neg.infinity = fcmp une half %fabs, 0xHFC001655 %ord = fcmp une half %x, 0.01656 %class = or i1 %fabs.une.neg.infinity, %ord1657 ret i1 %class1658}1659 1660; -> une1661define i1 @fabs_une_neginfinity_and_ord(half %x) #0 {1662; CHECK-LABEL: @fabs_une_neginfinity_and_ord(1663; CHECK-NEXT: [[ORD:%.*]] = fcmp une half [[X:%.*]], 0xH00001664; CHECK-NEXT: ret i1 [[ORD]]1665;1666 %fabs = call half @llvm.fabs.f16(half %x)1667 %fabs.une.neg.infinity = fcmp une half %fabs, 0xHFC001668 %ord = fcmp une half %x, 0.01669 %class = and i1 %fabs.une.neg.infinity, %ord1670 ret i1 %class1671}1672 1673; -> false1674define i1 @fabs_oeq_neginfinity_and_uge_smallest_normal(half %x) #0 {1675; CHECK-LABEL: @fabs_oeq_neginfinity_and_uge_smallest_normal(1676; CHECK-NEXT: ret i1 false1677;1678 %fabs = call half @llvm.fabs.f16(half %x)1679 %fabs.oeq.neg.infinity = fcmp oeq half %fabs, 0xHFC001680 %cmp.smallest.normal = fcmp oeq half %x, 0xH04001681 %class = and i1 %fabs.oeq.neg.infinity, %cmp.smallest.normal1682 ret i1 %class1683}1684 1685; -> false1686define i1 @fabs_oeq_neginfinity_or_uge_smallest_normal(half %x) #0 {1687; CHECK-LABEL: @fabs_oeq_neginfinity_or_uge_smallest_normal(1688; CHECK-NEXT: [[CMP_SMALLEST_NORMAL:%.*]] = fcmp oeq half [[X:%.*]], 0xH04001689; CHECK-NEXT: ret i1 [[CMP_SMALLEST_NORMAL]]1690;1691 %fabs = call half @llvm.fabs.f16(half %x)1692 %fabs.oeq.neg.infinity = fcmp oeq half %fabs, 0xHFC001693 %cmp.smallest.normal = fcmp oeq half %x, 0xH04001694 %class = or i1 %fabs.oeq.neg.infinity, %cmp.smallest.normal1695 ret i1 %class1696}1697 1698;- > ord1699define i1 @fabs_oeq_neginfinity_and_ord(half %x) #0 {1700; CHECK-LABEL: @fabs_oeq_neginfinity_and_ord(1701; CHECK-NEXT: ret i1 false1702;1703 %fabs = call half @llvm.fabs.f16(half %x)1704 %fabs.oeq.neg.infinity = fcmp oeq half %fabs, 0xHFC001705 %ord = fcmp ord half %x, 0.01706 %class = and i1 %fabs.oeq.neg.infinity, %ord1707 ret i1 %class1708}1709 1710; -> false1711define i1 @fabs_ueq_neginfinity_and_olt_smallest_normal(half %x) #0 { ; WRONG1712; CHECK-LABEL: @fabs_ueq_neginfinity_and_olt_smallest_normal(1713; CHECK-NEXT: ret i1 false1714;1715 %fabs = call half @llvm.fabs.f16(half %x)1716 %fabs.ueq.neg.infinity = fcmp ueq half %fabs, 0xHFC001717 %cmp.smallest.normal = fcmp olt half %x, 0xH04001718 %class = and i1 %fabs.ueq.neg.infinity, %cmp.smallest.normal1719 ret i1 %class1720}1721 1722; -> pinf|pnormal1723define i1 @fabs_one_neginfinity_and_uge_smallest_normal(half %x) #0 {1724; CHECK-LABEL: @fabs_one_neginfinity_and_uge_smallest_normal(1725; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 768)1726; CHECK-NEXT: ret i1 [[CLASS]]1727;1728 %fabs = call half @llvm.fabs.f16(half %x)1729 %fabs.one.neg.infinity = fcmp one half %fabs, 0xHFC001730 %cmp.smallest.normal = fcmp uge half %x, 0xH04001731 %class = and i1 %fabs.one.neg.infinity, %cmp.smallest.normal1732 ret i1 %class1733}1734 1735; -> ord1736define i1 @fabs_one_neginfinity_or_olt_smallest_normal(half %x) #0 {1737; CHECK-LABEL: @fabs_one_neginfinity_or_olt_smallest_normal(1738; CHECK-NEXT: [[CLASS:%.*]] = fcmp ord half [[X:%.*]], 0xH00001739; CHECK-NEXT: ret i1 [[CLASS]]1740;1741 %fabs = call half @llvm.fabs.f16(half %x)1742 %fabs.one.neg.infinity = fcmp one half %fabs, 0xHFC001743 %cmp.smallest.normal = fcmp olt half %x, 0xH04001744 %class = or i1 %fabs.one.neg.infinity, %cmp.smallest.normal1745 ret i1 %class1746}1747 1748; -> ~(zero|subnormal)1749define i1 @fabs_ueq_neginfinity_or_fabs_uge_smallest_normal(half %x) #0 {1750; CHECK-LABEL: @fabs_ueq_neginfinity_or_fabs_uge_smallest_normal(1751; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 783)1752; CHECK-NEXT: ret i1 [[CLASS]]1753;1754 %fabs = call half @llvm.fabs.f16(half %x)1755 %fabs.oeq.neg.infinity = fcmp ueq half %fabs, 0xHFC001756 %cmp.smallest.normal = fcmp uge half %fabs, 0xH04001757 %class = or i1 %fabs.oeq.neg.infinity, %cmp.smallest.normal1758 ret i1 %class1759}1760 1761; --------------------------------------------------------------------1762; Test denormal mode handling with x == 01763; --------------------------------------------------------------------1764 1765; Base pattern !isfinite(x) || x == 0.0, with input denormals flushed to 01766define i1 @not_isfinite_or_zero_f16_daz(half %x) #1 {1767; CHECK-LABEL: @not_isfinite_or_zero_f16_daz(1768; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])1769; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C001770; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH00001771; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]]1772; CHECK-NEXT: ret i1 [[CLASS]]1773;1774 %fabs = call half @llvm.fabs.f16(half %x)1775 %cmpinf = fcmp ueq half %fabs, 0xH7C001776 %cmpzero = fcmp oeq half %x, 0xH00001777 %class = or i1 %cmpzero, %cmpinf1778 ret i1 %class1779}1780 1781define <2 x i1> @not_isfinite_or_zero_v2f16_daz(<2 x half> %x) #1 {1782; CHECK-LABEL: @not_isfinite_or_zero_v2f16_daz(1783; CHECK-NEXT: [[FABS:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]])1784; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq <2 x half> [[FABS]], splat (half 0xH7C00)1785; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq <2 x half> [[X]], zeroinitializer1786; CHECK-NEXT: [[CLASS:%.*]] = or <2 x i1> [[CMPZERO]], [[CMPINF]]1787; CHECK-NEXT: ret <2 x i1> [[CLASS]]1788;1789 %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)1790 %cmpinf = fcmp ueq <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>1791 %cmpzero = fcmp oeq <2 x half> %x, zeroinitializer1792 %class = or <2 x i1> %cmpzero, %cmpinf1793 ret <2 x i1> %class1794}1795 1796; Base pattern !isfinite(x) || x == 0.0, with unknown input denormal treatment1797define i1 @not_isfinite_or_zero_f16_dynamic(half %x) #2 {1798; CHECK-LABEL: @not_isfinite_or_zero_f16_dynamic(1799; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])1800; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[FABS]], 0xH7C001801; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq half [[X]], 0xH00001802; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMPZERO]], [[CMPINF]]1803; CHECK-NEXT: ret i1 [[CLASS]]1804;1805 %fabs = call half @llvm.fabs.f16(half %x)1806 %cmpinf = fcmp ueq half %fabs, 0xH7C001807 %cmpzero = fcmp oeq half %x, 0xH00001808 %class = or i1 %cmpzero, %cmpinf1809 ret i1 %class1810}1811 1812define <2 x i1> @not_isfinite_or_zero_v2f16_dynamic(<2 x half> %x) #2 {1813; CHECK-LABEL: @not_isfinite_or_zero_v2f16_dynamic(1814; CHECK-NEXT: [[FABS:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]])1815; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq <2 x half> [[FABS]], splat (half 0xH7C00)1816; CHECK-NEXT: [[CMPZERO:%.*]] = fcmp oeq <2 x half> [[X]], zeroinitializer1817; CHECK-NEXT: [[CLASS:%.*]] = or <2 x i1> [[CMPZERO]], [[CMPINF]]1818; CHECK-NEXT: ret <2 x i1> [[CLASS]]1819;1820 %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)1821 %cmpinf = fcmp ueq <2 x half> %fabs, <half 0xH7C00, half 0xH7C00>1822 %cmpzero = fcmp oeq <2 x half> %x, zeroinitializer1823 %class = or <2 x i1> %cmpzero, %cmpinf1824 ret <2 x i1> %class1825}1826 1827define i1 @not_zero_and_subnormal_daz(half %x) #1 {1828; CHECK-LABEL: @not_zero_and_subnormal_daz(1829; CHECK-NEXT: [[OR:%.*]] = fcmp ord half [[X:%.*]], 0xH00001830; CHECK-NEXT: ret i1 [[OR]]1831;1832 %fabs = call half @llvm.fabs.f16(half %x)1833 %cmp.zero = fcmp one half %fabs, 0.01834 %cmp.smallest.normal = fcmp olt half %fabs, 0xH04001835 %or = or i1 %cmp.smallest.normal, %cmp.zero1836 ret i1 %or1837}1838 1839define i1 @not_zero_and_subnormal_dynamic(half %x) #2 {1840; CHECK-LABEL: @not_zero_and_subnormal_dynamic(1841; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])1842; CHECK-NEXT: [[CMP_ZERO:%.*]] = fcmp one half [[X]], 0xH00001843; CHECK-NEXT: [[CMP_SMALLEST_NORMAL:%.*]] = fcmp olt half [[FABS]], 0xH04001844; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP_SMALLEST_NORMAL]], [[CMP_ZERO]]1845; CHECK-NEXT: ret i1 [[OR]]1846;1847 %fabs = call half @llvm.fabs.f16(half %x)1848 %cmp.zero = fcmp one half %fabs, 0.01849 %cmp.smallest.normal = fcmp olt half %fabs, 0xH04001850 %or = or i1 %cmp.smallest.normal, %cmp.zero1851 ret i1 %or1852}1853 1854; TODO: This could fold to just fcmp olt half %fabs, 0xH04001855define i1 @subnormal_or_zero_ieee(half %x) #0 {1856; CHECK-LABEL: @subnormal_or_zero_ieee(1857; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240)1858; CHECK-NEXT: ret i1 [[AND]]1859;1860 %fabs = call half @llvm.fabs.f16(half %x)1861 %is.subnormal = fcmp olt half %fabs, 0xH04001862 %is.zero = fcmp oeq half %x, 0xH00001863 %and = or i1 %is.subnormal, %is.zero1864 ret i1 %and1865}1866 1867define i1 @subnormal_or_zero_daz(half %x) #1 {1868; CHECK-LABEL: @subnormal_or_zero_daz(1869; CHECK-NEXT: [[AND:%.*]] = fcmp oeq half [[X:%.*]], 0xH00001870; CHECK-NEXT: ret i1 [[AND]]1871;1872 %fabs = call half @llvm.fabs.f16(half %x)1873 %is.subnormal = fcmp olt half %fabs, 0xH04001874 %is.zero = fcmp oeq half %x, 0xH00001875 %and = or i1 %is.subnormal, %is.zero1876 ret i1 %and1877}1878 1879define i1 @subnormal_or_zero_dynamic(half %x) #2 {1880; CHECK-LABEL: @subnormal_or_zero_dynamic(1881; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])1882; CHECK-NEXT: [[IS_SUBNORMAL:%.*]] = fcmp olt half [[FABS]], 0xH04001883; CHECK-NEXT: [[IS_ZERO:%.*]] = fcmp oeq half [[X]], 0xH00001884; CHECK-NEXT: [[AND:%.*]] = or i1 [[IS_SUBNORMAL]], [[IS_ZERO]]1885; CHECK-NEXT: ret i1 [[AND]]1886;1887 %fabs = call half @llvm.fabs.f16(half %x)1888 %is.subnormal = fcmp olt half %fabs, 0xH04001889 %is.zero = fcmp oeq half %x, 0xH00001890 %and = or i1 %is.subnormal, %is.zero1891 ret i1 %and1892}1893 1894define i1 @issubnormal_or_inf_nnan_logical_select(half %x) {1895; CHECK-LABEL: @issubnormal_or_inf_nnan_logical_select(1896; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 756)1897; CHECK-NEXT: ret i1 [[CLASS]]1898;1899 %fabs = call nnan half @llvm.fabs.f16(half %x)1900 %cmpinf = fcmp nnan oeq half %fabs, 0xH7C001901 %cmp.smallest.normal = fcmp nnan olt half %fabs, 0xH04001902 %class = select i1 %cmpinf, i1 true, i1 %cmp.smallest.normal1903 ret i1 %class1904}1905 1906define i1 @issubnormal_and_ninf_nnan_logical_select(half %x) {1907; CHECK-LABEL: @issubnormal_and_ninf_nnan_logical_select(1908; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240)1909; CHECK-NEXT: ret i1 [[CLASS]]1910;1911 %fabs = call nnan half @llvm.fabs.f16(half %x)1912 %cmpinf = fcmp nnan one half %fabs, 0xH7C001913 %cmp.smallest.normal = fcmp nnan olt half %fabs, 0xH04001914 %class = select i1 %cmpinf, i1 %cmp.smallest.normal, i1 false1915 ret i1 %class1916}1917 1918define i1 @fcmp_ueq_neginf_or_oge_zero_f16(half %x) {1919; CHECK-LABEL: @fcmp_ueq_neginf_or_oge_zero_f16(1920; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 999)1921; CHECK-NEXT: ret i1 [[CLASS]]1922;1923 %cmpinf = fcmp ueq half %x, 0xHFC001924 %cmp.oge.zero = fcmp oge half %x, 0xH00001925 %class = or i1 %cmp.oge.zero, %cmpinf1926 ret i1 %class1927}1928 1929define i1 @fcmp_oeq_neginf_or_oge_zero_f16(half %x) {1930; CHECK-LABEL: @fcmp_oeq_neginf_or_oge_zero_f16(1931; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 996)1932; CHECK-NEXT: ret i1 [[CLASS]]1933;1934 %cmpinf = fcmp oeq half %x, 0xHFC001935 %cmp.oge.zero = fcmp oge half %x, 0xH00001936 %class = or i1 %cmp.oge.zero, %cmpinf1937 ret i1 %class1938}1939 1940define i1 @fcmp_ueq_neginf_or_oge_zero_f16_daz(half %x) #1 {1941; CHECK-LABEL: @fcmp_ueq_neginf_or_oge_zero_f16_daz(1942; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xHFC001943; CHECK-NEXT: [[CMP_OGE_ZERO:%.*]] = fcmp oge half [[X]], 0xH00001944; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OGE_ZERO]], [[CMPINF]]1945; CHECK-NEXT: ret i1 [[CLASS]]1946;1947 %cmpinf = fcmp ueq half %x, 0xHFC001948 %cmp.oge.zero = fcmp oge half %x, 0xH00001949 %class = or i1 %cmp.oge.zero, %cmpinf1950 ret i1 %class1951}1952 1953define i1 @fcmp_oeq_neginf_or_oge_zero_f16_daz(half %x) #1 {1954; CHECK-LABEL: @fcmp_oeq_neginf_or_oge_zero_f16_daz(1955; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC001956; CHECK-NEXT: [[CMP_OGE_ZERO:%.*]] = fcmp oge half [[X]], 0xH00001957; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OGE_ZERO]], [[CMPINF]]1958; CHECK-NEXT: ret i1 [[CLASS]]1959;1960 %cmpinf = fcmp oeq half %x, 0xHFC001961 %cmp.oge.zero = fcmp oge half %x, 0xH00001962 %class = or i1 %cmp.oge.zero, %cmpinf1963 ret i1 %class1964}1965 1966define i1 @fcmp_oeq_neginf_or_ogt_zero_f16(half %x) {1967; CHECK-LABEL: @fcmp_oeq_neginf_or_ogt_zero_f16(1968; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 900)1969; CHECK-NEXT: ret i1 [[CLASS]]1970;1971 %cmpinf = fcmp oeq half %x, 0xHFC001972 %cmp.ogt.zero = fcmp ogt half %x, 0xH00001973 %class = or i1 %cmp.ogt.zero, %cmpinf1974 ret i1 %class1975}1976 1977define i1 @fcmp_ueq_neginf_or_ogt_zero_f16(half %x) {1978; CHECK-LABEL: @fcmp_ueq_neginf_or_ogt_zero_f16(1979; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 903)1980; CHECK-NEXT: ret i1 [[CLASS]]1981;1982 %cmpinf = fcmp ueq half %x, 0xHFC001983 %cmp.ogt.zero = fcmp ogt half %x, 0xH00001984 %class = or i1 %cmp.ogt.zero, %cmpinf1985 ret i1 %class1986}1987 1988define i1 @fcmp_ueq_neginf_or_ogt_zero_f16_daz(half %x) #1 {1989; CHECK-LABEL: @fcmp_ueq_neginf_or_ogt_zero_f16_daz(1990; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xHFC001991; CHECK-NEXT: [[CMP_OGT_ZERO:%.*]] = fcmp ogt half [[X]], 0xH00001992; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OGT_ZERO]], [[CMPINF]]1993; CHECK-NEXT: ret i1 [[CLASS]]1994;1995 %cmpinf = fcmp ueq half %x, 0xHFC001996 %cmp.ogt.zero = fcmp ogt half %x, 0xH00001997 %class = or i1 %cmp.ogt.zero, %cmpinf1998 ret i1 %class1999}2000 2001define i1 @fcmp_oeq_neginf_or_ogt_zero_f16_daz(half %x) #1 {2002; CHECK-LABEL: @fcmp_oeq_neginf_or_ogt_zero_f16_daz(2003; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC002004; CHECK-NEXT: [[CMP_OGT_ZERO:%.*]] = fcmp ogt half [[X]], 0xH00002005; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OGT_ZERO]], [[CMPINF]]2006; CHECK-NEXT: ret i1 [[CLASS]]2007;2008 %cmpinf = fcmp oeq half %x, 0xHFC002009 %cmp.ogt.zero = fcmp ogt half %x, 0xH00002010 %class = or i1 %cmp.ogt.zero, %cmpinf2011 ret i1 %class2012}2013 2014define i1 @fcmp_oeq_neginf_or_ugt_zero_f16(half %x) {2015; CHECK-LABEL: @fcmp_oeq_neginf_or_ugt_zero_f16(2016; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 903)2017; CHECK-NEXT: ret i1 [[CLASS]]2018;2019 %cmpinf = fcmp oeq half %x, 0xHFC002020 %cmp.ugt.zero = fcmp ugt half %x, 0xH00002021 %class = or i1 %cmp.ugt.zero, %cmpinf2022 ret i1 %class2023}2024 2025define i1 @fcmp_ueq_neginf_or_ugt_zero_f16_daz(half %x) #1 {2026; CHECK-LABEL: @fcmp_ueq_neginf_or_ugt_zero_f16_daz(2027; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xHFC002028; CHECK-NEXT: [[CMP_UGT_ZERO:%.*]] = fcmp ugt half [[X]], 0xH00002029; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_UGT_ZERO]], [[CMPINF]]2030; CHECK-NEXT: ret i1 [[CLASS]]2031;2032 %cmpinf = fcmp ueq half %x, 0xHFC002033 %cmp.ugt.zero = fcmp ugt half %x, 0xH00002034 %class = or i1 %cmp.ugt.zero, %cmpinf2035 ret i1 %class2036}2037 2038define i1 @fcmp_oeq_neginf_or_ugt_zero_f16_daz(half %x) #1 {2039; CHECK-LABEL: @fcmp_oeq_neginf_or_ugt_zero_f16_daz(2040; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC002041; CHECK-NEXT: [[CMP_UGT_ZERO:%.*]] = fcmp ugt half [[X]], 0xH00002042; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_UGT_ZERO]], [[CMPINF]]2043; CHECK-NEXT: ret i1 [[CLASS]]2044;2045 %cmpinf = fcmp oeq half %x, 0xHFC002046 %cmp.ugt.zero = fcmp ugt half %x, 0xH00002047 %class = or i1 %cmp.ugt.zero, %cmpinf2048 ret i1 %class2049}2050 2051define i1 @fcmp_ueq_posinf_or_ole_zero_f16(half %x) {2052; CHECK-LABEL: @fcmp_ueq_posinf_or_ole_zero_f16(2053; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 639)2054; CHECK-NEXT: ret i1 [[CLASS]]2055;2056 %cmpinf = fcmp ueq half %x, 0xH7C002057 %cmp.ole.zero = fcmp ole half %x, 0xH00002058 %class = or i1 %cmp.ole.zero, %cmpinf2059 ret i1 %class2060}2061 2062define i1 @fcmp_oeq_posinf_or_ole_zero_f16(half %x) {2063; CHECK-LABEL: @fcmp_oeq_posinf_or_ole_zero_f16(2064; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 636)2065; CHECK-NEXT: ret i1 [[CLASS]]2066;2067 %cmpinf = fcmp oeq half %x, 0xH7C002068 %cmp.ole.zero = fcmp ole half %x, 0xH00002069 %class = or i1 %cmp.ole.zero, %cmpinf2070 ret i1 %class2071}2072 2073define i1 @fcmp_ueq_posinf_or_ole_zero_f16_daz(half %x) #1 {2074; CHECK-LABEL: @fcmp_ueq_posinf_or_ole_zero_f16_daz(2075; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xH7C002076; CHECK-NEXT: [[CMP_OLE_ZERO:%.*]] = fcmp ole half [[X]], 0xH00002077; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OLE_ZERO]], [[CMPINF]]2078; CHECK-NEXT: ret i1 [[CLASS]]2079;2080 %cmpinf = fcmp ueq half %x, 0xH7C002081 %cmp.ole.zero = fcmp ole half %x, 0xH00002082 %class = or i1 %cmp.ole.zero, %cmpinf2083 ret i1 %class2084}2085 2086define i1 @fcmp_oeq_posinf_or_ole_zero_f16_daz(half %x) #1 {2087; CHECK-LABEL: @fcmp_oeq_posinf_or_ole_zero_f16_daz(2088; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C002089; CHECK-NEXT: [[CMP_OLE_ZERO:%.*]] = fcmp ole half [[X]], 0xH00002090; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OLE_ZERO]], [[CMPINF]]2091; CHECK-NEXT: ret i1 [[CLASS]]2092;2093 %cmpinf = fcmp oeq half %x, 0xH7C002094 %cmp.ole.zero = fcmp ole half %x, 0xH00002095 %class = or i1 %cmp.ole.zero, %cmpinf2096 ret i1 %class2097}2098 2099define i1 @fcmp_oeq_posinf_or_olt_zero_f16(half %x) {2100; CHECK-LABEL: @fcmp_oeq_posinf_or_olt_zero_f16(2101; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 540)2102; CHECK-NEXT: ret i1 [[CLASS]]2103;2104 %cmpinf = fcmp oeq half %x, 0xH7C002105 %cmp.olt.zero = fcmp olt half %x, 0xH00002106 %class = or i1 %cmp.olt.zero, %cmpinf2107 ret i1 %class2108}2109 2110define i1 @fcmp_oeq_posinf_or_olt_zero_f16_daz(half %x) #1 {2111; CHECK-LABEL: @fcmp_oeq_posinf_or_olt_zero_f16_daz(2112; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C002113; CHECK-NEXT: [[CMP_OLT_ZERO:%.*]] = fcmp olt half [[X]], 0xH00002114; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_OLT_ZERO]], [[CMPINF]]2115; CHECK-NEXT: ret i1 [[CLASS]]2116;2117 %cmpinf = fcmp oeq half %x, 0xH7C002118 %cmp.olt.zero = fcmp olt half %x, 0xH00002119 %class = or i1 %cmp.olt.zero, %cmpinf2120 ret i1 %class2121}2122 2123define i1 @fcmp_ueq_posinf_or_ult_zero_f16(half %x) {2124; CHECK-LABEL: @fcmp_ueq_posinf_or_ult_zero_f16(2125; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 543)2126; CHECK-NEXT: ret i1 [[CLASS]]2127;2128 %cmpinf = fcmp ueq half %x, 0xH7C002129 %cmp.ult.zero = fcmp ult half %x, 0xH00002130 %class = or i1 %cmp.ult.zero, %cmpinf2131 ret i1 %class2132}2133 2134define i1 @fcmp_oeq_posinf_or_ult_zero_f16(half %x) {2135; CHECK-LABEL: @fcmp_oeq_posinf_or_ult_zero_f16(2136; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 543)2137; CHECK-NEXT: ret i1 [[CLASS]]2138;2139 %cmpinf = fcmp oeq half %x, 0xH7C002140 %cmp.ult.zero = fcmp ult half %x, 0xH00002141 %class = or i1 %cmp.ult.zero, %cmpinf2142 ret i1 %class2143}2144 2145define i1 @fcmp_ueq_posinf_or_ult_zero_f16_daz(half %x) #1 {2146; CHECK-LABEL: @fcmp_ueq_posinf_or_ult_zero_f16_daz(2147; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xH7C002148; CHECK-NEXT: [[CMP_ULT_ZERO:%.*]] = fcmp ult half [[X]], 0xH00002149; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_ULT_ZERO]], [[CMPINF]]2150; CHECK-NEXT: ret i1 [[CLASS]]2151;2152 %cmpinf = fcmp ueq half %x, 0xH7C002153 %cmp.ult.zero = fcmp ult half %x, 0xH00002154 %class = or i1 %cmp.ult.zero, %cmpinf2155 ret i1 %class2156}2157 2158define i1 @fcmp_oeq_posinf_or_ult_zero_f16_daz(half %x) #1 {2159; CHECK-LABEL: @fcmp_oeq_posinf_or_ult_zero_f16_daz(2160; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C002161; CHECK-NEXT: [[CMP_ULT_ZERO:%.*]] = fcmp ult half [[X]], 0xH00002162; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_ULT_ZERO]], [[CMPINF]]2163; CHECK-NEXT: ret i1 [[CLASS]]2164;2165 %cmpinf = fcmp oeq half %x, 0xH7C002166 %cmp.ult.zero = fcmp ult half %x, 0xH00002167 %class = or i1 %cmp.ult.zero, %cmpinf2168 ret i1 %class2169}2170 2171define i1 @fcmp_ueq_posinf_or_ule_zero_f16(half %x) {2172; CHECK-LABEL: @fcmp_ueq_posinf_or_ule_zero_f16(2173; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 639)2174; CHECK-NEXT: ret i1 [[CLASS]]2175;2176 %cmpinf = fcmp ueq half %x, 0xH7C002177 %cmp.ule.zero = fcmp ule half %x, 0xH00002178 %class = or i1 %cmp.ule.zero, %cmpinf2179 ret i1 %class2180}2181 2182define i1 @fcmp_ueq_posinf_or_ule_zero_f16_daz(half %x) #1 {2183; CHECK-LABEL: @fcmp_ueq_posinf_or_ule_zero_f16_daz(2184; CHECK-NEXT: [[CMPINF:%.*]] = fcmp ueq half [[X:%.*]], 0xH7C002185; CHECK-NEXT: [[CMP_ULE_ZERO:%.*]] = fcmp ule half [[X]], 0xH00002186; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_ULE_ZERO]], [[CMPINF]]2187; CHECK-NEXT: ret i1 [[CLASS]]2188;2189 %cmpinf = fcmp ueq half %x, 0xH7C002190 %cmp.ule.zero = fcmp ule half %x, 0xH00002191 %class = or i1 %cmp.ule.zero, %cmpinf2192 ret i1 %class2193}2194 2195define i1 @fcmp_oeq_posinf_or_ule_zero_f16_daz(half %x) #1 {2196; CHECK-LABEL: @fcmp_oeq_posinf_or_ule_zero_f16_daz(2197; CHECK-NEXT: [[CMPINF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C002198; CHECK-NEXT: [[CMP_ULE_ZERO:%.*]] = fcmp ule half [[X]], 0xH00002199; CHECK-NEXT: [[CLASS:%.*]] = or i1 [[CMP_ULE_ZERO]], [[CMPINF]]2200; CHECK-NEXT: ret i1 [[CLASS]]2201;2202 %cmpinf = fcmp oeq half %x, 0xH7C002203 %cmp.ule.zero = fcmp ule half %x, 0xH00002204 %class = or i1 %cmp.ule.zero, %cmpinf2205 ret i1 %class2206}2207 2208define i1 @fcmp_ueq_posinf_or_olt_zero_f16(half %x) {2209; CHECK-LABEL: @fcmp_ueq_posinf_or_olt_zero_f16(2210; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 543)2211; CHECK-NEXT: ret i1 [[CLASS]]2212;2213 %cmpinf = fcmp ueq half %x, 0xH7C002214 %cmp.olt.zero = fcmp olt half %x, 0xH00002215 %class = or i1 %cmp.olt.zero, %cmpinf2216 ret i1 %class2217}2218 2219declare half @llvm.fabs.f16(half) #02220declare half @llvm.canonicalize.f16(half) #02221declare <2 x half> @llvm.fabs.v2f16(<2 x half>) #02222 2223attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }2224attributes #1 = { "denormal-fp-math"="ieee,preserve-sign" }2225attributes #2 = { "denormal-fp-math"="ieee,dynamic" }2226