440 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=instcombine < %s | FileCheck %s3 4define i1 @fcmp_oeq_inf_or_class_normal(half %x) {5; CHECK-LABEL: @fcmp_oeq_inf_or_class_normal(6; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 776)7; CHECK-NEXT: ret i1 [[CLASS]]8;9 %oeq.inf = fcmp oeq half %x, 0xH7C0010 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)11 %or = or i1 %oeq.inf, %class12 ret i1 %or13}14 15define i1 @class_normal_or_fcmp_oeq_inf(half %x) {16; CHECK-LABEL: @class_normal_or_fcmp_oeq_inf(17; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 776)18; CHECK-NEXT: ret i1 [[CLASS]]19;20 %oeq.inf = fcmp oeq half %x, 0xH7C0021 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)22 %or = or i1 %class, %oeq.inf23 ret i1 %or24}25 26define <2 x i1> @fcmp_oeq_inf_or_class_normal_vector(<2 x half> %x) {27; CHECK-LABEL: @fcmp_oeq_inf_or_class_normal_vector(28; CHECK-NEXT: [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X:%.*]], i32 776)29; CHECK-NEXT: ret <2 x i1> [[CLASS]]30;31 %oeq.inf = fcmp oeq <2 x half> %x, <half 0xH7C00, half 0xH7C00>32 %class = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> %x, i32 264)33 %or = or <2 x i1> %oeq.inf, %class34 ret <2 x i1> %or35}36 37define i1 @fcmp_oeq_inf_multi_use_or_class_normal(half %x, ptr %ptr) {38; CHECK-LABEL: @fcmp_oeq_inf_multi_use_or_class_normal(39; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C0040; CHECK-NEXT: store i1 [[OEQ_INF]], ptr [[PTR:%.*]], align 141; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)42; CHECK-NEXT: [[OR:%.*]] = or i1 [[OEQ_INF]], [[CLASS]]43; CHECK-NEXT: ret i1 [[OR]]44;45 %oeq.inf = fcmp oeq half %x, 0xH7C0046 store i1 %oeq.inf, ptr %ptr47 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)48 %or = or i1 %oeq.inf, %class49 ret i1 %or50}51 52define i1 @fcmp_oeq_inf_or_class_normal_multi_use(half %x, ptr %ptr) {53; CHECK-LABEL: @fcmp_oeq_inf_or_class_normal_multi_use(54; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C0055; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)56; CHECK-NEXT: store i1 [[CLASS]], ptr [[PTR:%.*]], align 157; CHECK-NEXT: [[OR:%.*]] = or i1 [[OEQ_INF]], [[CLASS]]58; CHECK-NEXT: ret i1 [[OR]]59;60 %oeq.inf = fcmp oeq half %x, 0xH7C0061 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)62 store i1 %class, ptr %ptr63 %or = or i1 %oeq.inf, %class64 ret i1 %or65}66 67; -> true68define i1 @fcmp_ord_or_class_isnan(half %x) {69; CHECK-LABEL: @fcmp_ord_or_class_isnan(70; CHECK-NEXT: ret i1 true71;72 %ord = fcmp ord half %x, 0.073 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 3)74 %or = or i1 %ord, %class75 ret i1 %or76}77 78define i1 @fcmp_ord_or_class_isnan_wrong_operand(half %x, half %y) {79; CHECK-LABEL: @fcmp_ord_or_class_isnan_wrong_operand(80; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH000081; CHECK-NEXT: [[CLASS:%.*]] = fcmp uno half [[Y:%.*]], 0xH000082; CHECK-NEXT: [[OR:%.*]] = or i1 [[ORD]], [[CLASS]]83; CHECK-NEXT: ret i1 [[OR]]84;85 %ord = fcmp ord half %x, 0.086 %class = call i1 @llvm.is.fpclass.f16(half %y, i32 3)87 %or = or i1 %ord, %class88 ret i1 %or89}90 91; -> false92define i1 @fcmp_ord_and_class_isnan(half %x) {93; CHECK-LABEL: @fcmp_ord_and_class_isnan(94; CHECK-NEXT: ret i1 false95;96 %ord = fcmp ord half %x, 0.097 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 3)98 %and = and i1 %ord, %class99 ret i1 %and100}101 102; -> true103define i1 @fcmp_ord_or_class_isnan_commute(half %x) {104; CHECK-LABEL: @fcmp_ord_or_class_isnan_commute(105; CHECK-NEXT: ret i1 true106;107 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 3)108 %ord = fcmp ord half %x, 0.0109 %or = or i1 %class, %ord110 ret i1 %or111}112 113; -> false114define i1 @fcmp_ord_and_class_isnan_commute(half %x) {115; CHECK-LABEL: @fcmp_ord_and_class_isnan_commute(116; CHECK-NEXT: ret i1 false117;118 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 3)119 %ord = fcmp ord half %x, 0.0120 %and = and i1 %class, %ord121 ret i1 %and122}123 124define i1 @fcmp_isfinite_and_class_subnormal(half %x) {125; CHECK-LABEL: @fcmp_isfinite_and_class_subnormal(126; CHECK-NEXT: [[SUBNORMAL_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 144)127; CHECK-NEXT: ret i1 [[SUBNORMAL_CLASS]]128;129 %fabs = call half @llvm.fabs.f16(half %x)130 %is.finite = fcmp olt half %fabs, 0xH7C00131 %subnormal.class = call i1 @llvm.is.fpclass.f16(half %x, i32 144)132 %and = and i1 %is.finite, %subnormal.class133 ret i1 %and134}135 136define i1 @fcmp_isfinite_or_class_subnormal(half %x) {137; CHECK-LABEL: @fcmp_isfinite_or_class_subnormal(138; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])139; CHECK-NEXT: [[SUBNORMAL_CLASS:%.*]] = fcmp one half [[TMP1]], 0xH7C00140; CHECK-NEXT: ret i1 [[SUBNORMAL_CLASS]]141;142 %fabs = call half @llvm.fabs.f16(half %x)143 %is.finite = fcmp olt half %fabs, 0xH7C00144 %subnormal.class = call i1 @llvm.is.fpclass.f16(half %x, i32 144)145 %or = or i1 %is.finite, %subnormal.class146 ret i1 %or147}148 149; -> isfinite150define i1 @fcmp_issubnormal_or_class_finite(half %x) {151; CHECK-LABEL: @fcmp_issubnormal_or_class_finite(152; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])153; CHECK-NEXT: [[OR:%.*]] = fcmp one half [[TMP1]], 0xH7C00154; CHECK-NEXT: ret i1 [[OR]]155;156 %fabs = call half @llvm.fabs.f16(half %x)157 %is.subnormal = fcmp olt half %fabs, 0xH0400158 %is.finite.class = call i1 @llvm.is.fpclass.f16(half %x, i32 504)159 %or = or i1 %is.subnormal, %is.finite.class160 ret i1 %or161}162 163; -> isfinite164define i1 @class_finite_or_fcmp_issubnormal(half %x) {165; CHECK-LABEL: @class_finite_or_fcmp_issubnormal(166; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])167; CHECK-NEXT: [[OR:%.*]] = fcmp one half [[TMP1]], 0xH7C00168; CHECK-NEXT: ret i1 [[OR]]169;170 %fabs = call half @llvm.fabs.f16(half %x)171 %is.subnormal = fcmp olt half %fabs, 0xH0400172 %is.finite.class = call i1 @llvm.is.fpclass.f16(half %x, i32 504)173 %or = or i1 %is.finite.class, %is.subnormal174 ret i1 %or175}176 177; -> issubnormal178define i1 @fcmp_issubnormal_and_class_finite(half %x) {179; CHECK-LABEL: @fcmp_issubnormal_and_class_finite(180; CHECK-NEXT: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240)181; CHECK-NEXT: ret i1 [[AND]]182;183 %fabs = call half @llvm.fabs.f16(half %x)184 %is.subnormal = fcmp olt half %fabs, 0xH0400185 %is.finite.class = call i1 @llvm.is.fpclass.f16(half %x, i32 504)186 %and = and i1 %is.subnormal, %is.finite.class187 ret i1 %and188}189 190define i1 @class_inf_or_fcmp_issubnormal(half %x) {191; CHECK-LABEL: @class_inf_or_fcmp_issubnormal(192; CHECK-NEXT: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 756)193; CHECK-NEXT: ret i1 [[OR]]194;195 %fabs = call half @llvm.fabs.f16(half %x)196 %is.subnormal = fcmp olt half %fabs, 0xH0400197 %is.inf.class = call i1 @llvm.is.fpclass.f16(half %x, i32 516)198 %or = or i1 %is.inf.class, %is.subnormal199 ret i1 %or200}201 202; -> isfinite203define <2 x i1> @class_finite_or_fcmp_issubnormal_vector(<2 x half> %x) {204; CHECK-LABEL: @class_finite_or_fcmp_issubnormal_vector(205; CHECK-NEXT: [[TMP1:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]])206; CHECK-NEXT: [[OR:%.*]] = fcmp one <2 x half> [[TMP1]], splat (half 0xH7C00)207; CHECK-NEXT: ret <2 x i1> [[OR]]208;209 %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)210 %is.subnormal = fcmp olt <2 x half> %fabs, <half 0xH0400, half 0xH0400>211 %is.finite.class = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> %x, i32 504)212 %or = or <2 x i1> %is.finite.class, %is.subnormal213 ret <2 x i1> %or214}215 216define i1 @fcmp_oeq_zero_or_class_normal(half %x) {217; CHECK-LABEL: @fcmp_oeq_zero_or_class_normal(218; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 360)219; CHECK-NEXT: ret i1 [[CLASS]]220;221 %oeq.inf = fcmp oeq half %x, 0.0222 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)223 %or = or i1 %oeq.inf, %class224 ret i1 %or225}226 227define i1 @fcmp_oeq_zero_or_class_normal_daz(half %x) #1 {228; CHECK-LABEL: @fcmp_oeq_zero_or_class_normal_daz(229; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH0000230; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)231; CHECK-NEXT: [[OR:%.*]] = or i1 [[OEQ_INF]], [[CLASS]]232; CHECK-NEXT: ret i1 [[OR]]233;234 %oeq.inf = fcmp oeq half %x, 0.0235 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)236 %or = or i1 %oeq.inf, %class237 ret i1 %or238}239 240define <2 x i1> @fcmp_oeq_zero_or_class_normal_daz_v2f16(<2 x half> %x) #1 {241; CHECK-LABEL: @fcmp_oeq_zero_or_class_normal_daz_v2f16(242; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq <2 x half> [[X:%.*]], zeroinitializer243; CHECK-NEXT: [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X]], i32 264)244; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[OEQ_INF]], [[CLASS]]245; CHECK-NEXT: ret <2 x i1> [[OR]]246;247 %oeq.inf = fcmp oeq <2 x half> %x, zeroinitializer248 %class = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> %x, i32 264)249 %or = or <2 x i1> %oeq.inf, %class250 ret <2 x i1> %or251}252 253define i1 @fcmp_oeq_zero_or_class_normal_dynamic(half %x) #2 {254; CHECK-LABEL: @fcmp_oeq_zero_or_class_normal_dynamic(255; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH0000256; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)257; CHECK-NEXT: [[OR:%.*]] = or i1 [[OEQ_INF]], [[CLASS]]258; CHECK-NEXT: ret i1 [[OR]]259;260 %oeq.inf = fcmp oeq half %x, 0.0261 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)262 %or = or i1 %oeq.inf, %class263 ret i1 %or264}265 266define <2 x i1> @fcmp_oeq_zero_or_class_normal_dynamic_v2f16(<2 x half> %x) #2 {267; CHECK-LABEL: @fcmp_oeq_zero_or_class_normal_dynamic_v2f16(268; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq <2 x half> [[X:%.*]], zeroinitializer269; CHECK-NEXT: [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X]], i32 264)270; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[OEQ_INF]], [[CLASS]]271; CHECK-NEXT: ret <2 x i1> [[OR]]272;273 %oeq.inf = fcmp oeq <2 x half> %x, zeroinitializer274 %class = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> %x, i32 264)275 %or = or <2 x i1> %oeq.inf, %class276 ret <2 x i1> %or277}278 279define i1 @class_normal_or_fcmp_oeq_zero(half %x) {280; CHECK-LABEL: @class_normal_or_fcmp_oeq_zero(281; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 360)282; CHECK-NEXT: ret i1 [[CLASS]]283;284 %oeq.inf = fcmp oeq half %x, 0.0285 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)286 %or = or i1 %oeq.inf, %class287 ret i1 %or288}289 290define i1 @fcmp_ueq_zero_or_class_normal(half %x) {291; CHECK-LABEL: @fcmp_ueq_zero_or_class_normal(292; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 363)293; CHECK-NEXT: ret i1 [[CLASS]]294;295 %ueq.inf = fcmp ueq half %x, 0.0296 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)297 %or = or i1 %ueq.inf, %class298 ret i1 %or299}300 301define i1 @class_normal_or_fcmp_ueq_zero(half %x) {302; CHECK-LABEL: @class_normal_or_fcmp_ueq_zero(303; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 363)304; CHECK-NEXT: ret i1 [[CLASS]]305;306 %ueq.inf = fcmp ueq half %x, 0.0307 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)308 %or = or i1 %ueq.inf, %class309 ret i1 %or310}311 312define i1 @fcmp_one_zero_or_class_normal(half %x) {313; CHECK-LABEL: @fcmp_one_zero_or_class_normal(314; CHECK-NEXT: [[CLASS:%.*]] = fcmp one half [[X:%.*]], 0xH0000315; CHECK-NEXT: ret i1 [[CLASS]]316;317 %one.inf = fcmp one half %x, 0.0318 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)319 %or = or i1 %one.inf, %class320 ret i1 %or321}322 323define i1 @fcmp_one_zero_or_class_normal_daz(half %x) #1 {324; CHECK-LABEL: @fcmp_one_zero_or_class_normal_daz(325; CHECK-NEXT: [[ONE_INF:%.*]] = fcmp one half [[X:%.*]], 0xH0000326; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)327; CHECK-NEXT: [[OR:%.*]] = or i1 [[ONE_INF]], [[CLASS]]328; CHECK-NEXT: ret i1 [[OR]]329;330 %one.inf = fcmp one half %x, 0.0331 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)332 %or = or i1 %one.inf, %class333 ret i1 %or334}335 336define i1 @fcmp_one_zero_or_class_normal_dynamic(half %x) #2 {337; CHECK-LABEL: @fcmp_one_zero_or_class_normal_dynamic(338; CHECK-NEXT: [[ONE_INF:%.*]] = fcmp one half [[X:%.*]], 0xH0000339; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)340; CHECK-NEXT: [[OR:%.*]] = or i1 [[ONE_INF]], [[CLASS]]341; CHECK-NEXT: ret i1 [[OR]]342;343 %one.inf = fcmp one half %x, 0.0344 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)345 %or = or i1 %one.inf, %class346 ret i1 %or347}348 349define i1 @class_normal_or_fcmp_one_zero(half %x) {350; CHECK-LABEL: @class_normal_or_fcmp_one_zero(351; CHECK-NEXT: [[CLASS:%.*]] = fcmp one half [[X:%.*]], 0xH0000352; CHECK-NEXT: ret i1 [[CLASS]]353;354 %one.inf = fcmp one half %x, 0.0355 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)356 %or = or i1 %one.inf, %class357 ret i1 %or358}359 360define i1 @fcmp_une_zero_or_class_normal(half %x) {361; CHECK-LABEL: @fcmp_une_zero_or_class_normal(362; CHECK-NEXT: [[CLASS:%.*]] = fcmp une half [[X:%.*]], 0xH0000363; CHECK-NEXT: ret i1 [[CLASS]]364;365 %une.inf = fcmp une half %x, 0.0366 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)367 %or = or i1 %une.inf, %class368 ret i1 %or369}370 371define i1 @class_normal_or_fcmp_une_zero(half %x) {372; CHECK-LABEL: @class_normal_or_fcmp_une_zero(373; CHECK-NEXT: [[CLASS:%.*]] = fcmp une half [[X:%.*]], 0xH0000374; CHECK-NEXT: ret i1 [[CLASS]]375;376 %une.inf = fcmp une half %x, 0.0377 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)378 %or = or i1 %une.inf, %class379 ret i1 %or380}381 382define i1 @class_normal_or_fcmp_une_zero_daz(half %x) #1 {383; CHECK-LABEL: @class_normal_or_fcmp_une_zero_daz(384; CHECK-NEXT: [[UNE_INF:%.*]] = fcmp une half [[X:%.*]], 0xH0000385; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)386; CHECK-NEXT: [[OR:%.*]] = or i1 [[UNE_INF]], [[CLASS]]387; CHECK-NEXT: ret i1 [[OR]]388;389 %une.inf = fcmp une half %x, 0.0390 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)391 %or = or i1 %une.inf, %class392 ret i1 %or393}394 395define i1 @class_normal_or_fcmp_une_zero_dynamic(half %x) #2 {396; CHECK-LABEL: @class_normal_or_fcmp_une_zero_dynamic(397; CHECK-NEXT: [[UNE_INF:%.*]] = fcmp une half [[X:%.*]], 0xH0000398; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264)399; CHECK-NEXT: [[OR:%.*]] = or i1 [[UNE_INF]], [[CLASS]]400; CHECK-NEXT: ret i1 [[OR]]401;402 %une.inf = fcmp une half %x, 0.0403 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)404 %or = or i1 %une.inf, %class405 ret i1 %or406}407 408define i1 @fcmp_oeq_inf_xor_class_normal(half %x) {409; CHECK-LABEL: @fcmp_oeq_inf_xor_class_normal(410; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 776)411; CHECK-NEXT: ret i1 [[CLASS]]412;413 %oeq.inf = fcmp oeq half %x, 0xH7C00414 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)415 %xor = xor i1 %oeq.inf, %class416 ret i1 %xor417}418 419define i1 @class_normal_xor_fcmp_oeq_inf(half %x) {420; CHECK-LABEL: @class_normal_xor_fcmp_oeq_inf(421; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 776)422; CHECK-NEXT: ret i1 [[CLASS]]423;424 %oeq.inf = fcmp oeq half %x, 0xH7C00425 %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264)426 %xor = xor i1 %class, %oeq.inf427 ret i1 %xor428}429 430 431declare half @llvm.fabs.f16(half) #0432declare half @llvm.canonicalize.f16(half) #0433declare <2 x half> @llvm.fabs.v2f16(<2 x half>) #0434declare i1 @llvm.is.fpclass.f16(half, i32 immarg) #0435declare <2 x i1> @llvm.is.fpclass.v2f16(<2 x half>, i32 immarg) #0436 437attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }438attributes #1 = { "denormal-fp-math"="ieee,preserve-sign" }439attributes #2 = { "denormal-fp-math"="ieee,dynamic" }440