From f532b024b1d11f1e77b9867b8927c7f89d6a382b Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Sun, 11 Dec 2022 21:48:41 -0500 Subject: [PATCH] InstCombine: Add baseline tests for is.fpclass with fcmp --- .../combine-is.fpclass-and-fcmp.ll | 388 ++++++++++++++++++ 1 file changed, 388 insertions(+) create mode 100644 llvm/test/Transforms/InstCombine/combine-is.fpclass-and-fcmp.ll diff --git a/llvm/test/Transforms/InstCombine/combine-is.fpclass-and-fcmp.ll b/llvm/test/Transforms/InstCombine/combine-is.fpclass-and-fcmp.ll new file mode 100644 index 0000000000000..35b5e67560677 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/combine-is.fpclass-and-fcmp.ll @@ -0,0 +1,388 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -passes=instcombine < %s | FileCheck %s + +define i1 @fcmp_oeq_inf_or_class_normal(half %x) { +; CHECK-LABEL: @fcmp_oeq_inf_or_class_normal( +; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00 +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264) +; CHECK-NEXT: [[OR:%.*]] = or i1 [[OEQ_INF]], [[CLASS]] +; CHECK-NEXT: ret i1 [[OR]] +; + %oeq.inf = fcmp oeq half %x, 0xH7C00 + %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264) + %or = or i1 %oeq.inf, %class + ret i1 %or +} + +define i1 @class_normal_or_fcmp_oeq_inf(half %x) { +; CHECK-LABEL: @class_normal_or_fcmp_oeq_inf( +; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00 +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264) +; CHECK-NEXT: [[OR:%.*]] = or i1 [[CLASS]], [[OEQ_INF]] +; CHECK-NEXT: ret i1 [[OR]] +; + %oeq.inf = fcmp oeq half %x, 0xH7C00 + %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264) + %or = or i1 %class, %oeq.inf + ret i1 %or +} + +define <2 x i1> @fcmp_oeq_inf_or_class_normal_vector(<2 x half> %x) { +; CHECK-LABEL: @fcmp_oeq_inf_or_class_normal_vector( +; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq <2 x half> [[X:%.*]], +; CHECK-NEXT: [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X]], i32 264) +; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[OEQ_INF]], [[CLASS]] +; CHECK-NEXT: ret <2 x i1> [[OR]] +; + %oeq.inf = fcmp oeq <2 x half> %x, + %class = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> %x, i32 264) + %or = or <2 x i1> %oeq.inf, %class + ret <2 x i1> %or +} + +define i1 @fcmp_oeq_inf_multi_use_or_class_normal(half %x, ptr %ptr) { +; CHECK-LABEL: @fcmp_oeq_inf_multi_use_or_class_normal( +; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00 +; CHECK-NEXT: store i1 [[OEQ_INF]], ptr [[PTR:%.*]], align 1 +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264) +; CHECK-NEXT: [[OR:%.*]] = or i1 [[OEQ_INF]], [[CLASS]] +; CHECK-NEXT: ret i1 [[OR]] +; + %oeq.inf = fcmp oeq half %x, 0xH7C00 + store i1 %oeq.inf, ptr %ptr + %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264) + %or = or i1 %oeq.inf, %class + ret i1 %or +} + +define i1 @fcmp_oeq_inf_or_class_normal_multi_use(half %x, ptr %ptr) { +; CHECK-LABEL: @fcmp_oeq_inf_or_class_normal_multi_use( +; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00 +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264) +; CHECK-NEXT: store i1 [[CLASS]], ptr [[PTR:%.*]], align 1 +; CHECK-NEXT: [[OR:%.*]] = or i1 [[OEQ_INF]], [[CLASS]] +; CHECK-NEXT: ret i1 [[OR]] +; + %oeq.inf = fcmp oeq half %x, 0xH7C00 + %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264) + store i1 %class, ptr %ptr + %or = or i1 %oeq.inf, %class + ret i1 %or +} + +; -> true +define i1 @fcmp_ord_or_class_isnan(half %x) { +; CHECK-LABEL: @fcmp_ord_or_class_isnan( +; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 3) +; CHECK-NEXT: [[OR:%.*]] = or i1 [[ORD]], [[CLASS]] +; CHECK-NEXT: ret i1 [[OR]] +; + %ord = fcmp ord half %x, 0.0 + %class = call i1 @llvm.is.fpclass.f16(half %x, i32 3) + %or = or i1 %ord, %class + ret i1 %or +} + +define i1 @fcmp_ord_or_class_isnan_wrong_operand(half %x, half %y) { +; CHECK-LABEL: @fcmp_ord_or_class_isnan_wrong_operand( +; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[Y:%.*]], i32 3) +; CHECK-NEXT: [[OR:%.*]] = or i1 [[ORD]], [[CLASS]] +; CHECK-NEXT: ret i1 [[OR]] +; + %ord = fcmp ord half %x, 0.0 + %class = call i1 @llvm.is.fpclass.f16(half %y, i32 3) + %or = or i1 %ord, %class + ret i1 %or +} + +; -> false +define i1 @fcmp_ord_and_class_isnan(half %x) { +; CHECK-LABEL: @fcmp_ord_and_class_isnan( +; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000 +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 3) +; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[CLASS]] +; CHECK-NEXT: ret i1 [[AND]] +; + %ord = fcmp ord half %x, 0.0 + %class = call i1 @llvm.is.fpclass.f16(half %x, i32 3) + %and = and i1 %ord, %class + ret i1 %and +} + +; -> true +define i1 @fcmp_ord_or_class_isnan_commute(half %x) { +; CHECK-LABEL: @fcmp_ord_or_class_isnan_commute( +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 3) +; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 +; CHECK-NEXT: [[OR:%.*]] = or i1 [[CLASS]], [[ORD]] +; CHECK-NEXT: ret i1 [[OR]] +; + %class = call i1 @llvm.is.fpclass.f16(half %x, i32 3) + %ord = fcmp ord half %x, 0.0 + %or = or i1 %class, %ord + ret i1 %or +} + +; -> false +define i1 @fcmp_ord_and_class_isnan_commute(half %x) { +; CHECK-LABEL: @fcmp_ord_and_class_isnan_commute( +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 3) +; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000 +; CHECK-NEXT: [[AND:%.*]] = and i1 [[CLASS]], [[ORD]] +; CHECK-NEXT: ret i1 [[AND]] +; + %class = call i1 @llvm.is.fpclass.f16(half %x, i32 3) + %ord = fcmp ord half %x, 0.0 + %and = and i1 %class, %ord + ret i1 %and +} + +define i1 @fcmp_isfinite_and_class_subnormal(half %x) { +; CHECK-LABEL: @fcmp_isfinite_and_class_subnormal( +; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) +; CHECK-NEXT: [[IS_FINITE:%.*]] = fcmp olt half [[FABS]], 0xH7C00 +; CHECK-NEXT: [[SUBNORMAL_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 144) +; CHECK-NEXT: [[AND:%.*]] = and i1 [[IS_FINITE]], [[SUBNORMAL_CLASS]] +; CHECK-NEXT: ret i1 [[AND]] +; + %fabs = call half @llvm.fabs.f16(half %x) + %is.finite = fcmp olt half %fabs, 0xH7C00 + %subnormal.class = call i1 @llvm.is.fpclass.f16(half %x, i32 144) + %and = and i1 %is.finite, %subnormal.class + ret i1 %and +} + +define i1 @fcmp_isfinite_or_class_subnormal(half %x) { +; CHECK-LABEL: @fcmp_isfinite_or_class_subnormal( +; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) +; CHECK-NEXT: [[IS_FINITE:%.*]] = fcmp olt half [[FABS]], 0xH7C00 +; CHECK-NEXT: [[SUBNORMAL_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 144) +; CHECK-NEXT: [[OR:%.*]] = or i1 [[IS_FINITE]], [[SUBNORMAL_CLASS]] +; CHECK-NEXT: ret i1 [[OR]] +; + %fabs = call half @llvm.fabs.f16(half %x) + %is.finite = fcmp olt half %fabs, 0xH7C00 + %subnormal.class = call i1 @llvm.is.fpclass.f16(half %x, i32 144) + %or = or i1 %is.finite, %subnormal.class + ret i1 %or +} + +; -> isfinite +define i1 @fcmp_issubnormal_or_class_finite(half %x) { +; CHECK-LABEL: @fcmp_issubnormal_or_class_finite( +; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) +; CHECK-NEXT: [[IS_SUBNORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400 +; CHECK-NEXT: [[IS_FINITE_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 504) +; CHECK-NEXT: [[OR:%.*]] = or i1 [[IS_SUBNORMAL]], [[IS_FINITE_CLASS]] +; CHECK-NEXT: ret i1 [[OR]] +; + %fabs = call half @llvm.fabs.f16(half %x) + %is.subnormal = fcmp olt half %fabs, 0xH0400 + %is.finite.class = call i1 @llvm.is.fpclass.f16(half %x, i32 504) + %or = or i1 %is.subnormal, %is.finite.class + ret i1 %or +} + +; -> isfinite +define i1 @class_finite_or_fcmp_issubnormal(half %x) { +; CHECK-LABEL: @class_finite_or_fcmp_issubnormal( +; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) +; CHECK-NEXT: [[IS_SUBNORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400 +; CHECK-NEXT: [[IS_FINITE_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 504) +; CHECK-NEXT: [[OR:%.*]] = or i1 [[IS_FINITE_CLASS]], [[IS_SUBNORMAL]] +; CHECK-NEXT: ret i1 [[OR]] +; + %fabs = call half @llvm.fabs.f16(half %x) + %is.subnormal = fcmp olt half %fabs, 0xH0400 + %is.finite.class = call i1 @llvm.is.fpclass.f16(half %x, i32 504) + %or = or i1 %is.finite.class, %is.subnormal + ret i1 %or +} + +; -> issubnormal +define i1 @fcmp_issubnormal_and_class_finite(half %x) { +; CHECK-LABEL: @fcmp_issubnormal_and_class_finite( +; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) +; CHECK-NEXT: [[IS_SUBNORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400 +; CHECK-NEXT: [[IS_FINITE_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 504) +; CHECK-NEXT: [[AND:%.*]] = and i1 [[IS_SUBNORMAL]], [[IS_FINITE_CLASS]] +; CHECK-NEXT: ret i1 [[AND]] +; + %fabs = call half @llvm.fabs.f16(half %x) + %is.subnormal = fcmp olt half %fabs, 0xH0400 + %is.finite.class = call i1 @llvm.is.fpclass.f16(half %x, i32 504) + %and = and i1 %is.subnormal, %is.finite.class + ret i1 %and +} + +define i1 @class_inf_or_fcmp_issubnormal(half %x) { +; CHECK-LABEL: @class_inf_or_fcmp_issubnormal( +; CHECK-NEXT: [[FABS:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) +; CHECK-NEXT: [[IS_SUBNORMAL:%.*]] = fcmp olt half [[FABS]], 0xH0400 +; CHECK-NEXT: [[IS_INF_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 516) +; CHECK-NEXT: [[OR:%.*]] = or i1 [[IS_INF_CLASS]], [[IS_SUBNORMAL]] +; CHECK-NEXT: ret i1 [[OR]] +; + %fabs = call half @llvm.fabs.f16(half %x) + %is.subnormal = fcmp olt half %fabs, 0xH0400 + %is.inf.class = call i1 @llvm.is.fpclass.f16(half %x, i32 516) + %or = or i1 %is.inf.class, %is.subnormal + ret i1 %or +} + +; -> isfinite +define <2 x i1> @class_finite_or_fcmp_issubnormal_vector(<2 x half> %x) { +; CHECK-LABEL: @class_finite_or_fcmp_issubnormal_vector( +; CHECK-NEXT: [[FABS:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]]) +; CHECK-NEXT: [[IS_SUBNORMAL:%.*]] = fcmp olt <2 x half> [[FABS]], +; CHECK-NEXT: [[IS_FINITE_CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X]], i32 504) +; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[IS_FINITE_CLASS]], [[IS_SUBNORMAL]] +; CHECK-NEXT: ret <2 x i1> [[OR]] +; + %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x) + %is.subnormal = fcmp olt <2 x half> %fabs, + %is.finite.class = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> %x, i32 504) + %or = or <2 x i1> %is.finite.class, %is.subnormal + ret <2 x i1> %or +} + +define i1 @fcmp_oeq_zero_or_class_normal(half %x) { +; CHECK-LABEL: @fcmp_oeq_zero_or_class_normal( +; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH0000 +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264) +; CHECK-NEXT: [[OR:%.*]] = or i1 [[OEQ_INF]], [[CLASS]] +; CHECK-NEXT: ret i1 [[OR]] +; + %oeq.inf = fcmp oeq half %x, 0.0 + %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264) + %or = or i1 %oeq.inf, %class + ret i1 %or +} + +define i1 @class_normal_or_fcmp_oeq_zero(half %x) { +; CHECK-LABEL: @class_normal_or_fcmp_oeq_zero( +; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH0000 +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264) +; CHECK-NEXT: [[OR:%.*]] = or i1 [[OEQ_INF]], [[CLASS]] +; CHECK-NEXT: ret i1 [[OR]] +; + %oeq.inf = fcmp oeq half %x, 0.0 + %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264) + %or = or i1 %oeq.inf, %class + ret i1 %or +} + +define i1 @fcmp_ueq_zero_or_class_normal(half %x) { +; CHECK-LABEL: @fcmp_ueq_zero_or_class_normal( +; CHECK-NEXT: [[UEQ_INF:%.*]] = fcmp ueq half [[X:%.*]], 0xH0000 +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264) +; CHECK-NEXT: [[OR:%.*]] = or i1 [[UEQ_INF]], [[CLASS]] +; CHECK-NEXT: ret i1 [[OR]] +; + %ueq.inf = fcmp ueq half %x, 0.0 + %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264) + %or = or i1 %ueq.inf, %class + ret i1 %or +} + +define i1 @class_normal_or_fcmp_ueq_zero(half %x) { +; CHECK-LABEL: @class_normal_or_fcmp_ueq_zero( +; CHECK-NEXT: [[UEQ_INF:%.*]] = fcmp ueq half [[X:%.*]], 0xH0000 +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264) +; CHECK-NEXT: [[OR:%.*]] = or i1 [[UEQ_INF]], [[CLASS]] +; CHECK-NEXT: ret i1 [[OR]] +; + %ueq.inf = fcmp ueq half %x, 0.0 + %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264) + %or = or i1 %ueq.inf, %class + ret i1 %or +} + +define i1 @fcmp_one_zero_or_class_normal(half %x) { +; CHECK-LABEL: @fcmp_one_zero_or_class_normal( +; CHECK-NEXT: [[ONE_INF:%.*]] = fcmp one half [[X:%.*]], 0xH0000 +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264) +; CHECK-NEXT: [[OR:%.*]] = or i1 [[ONE_INF]], [[CLASS]] +; CHECK-NEXT: ret i1 [[OR]] +; + %one.inf = fcmp one half %x, 0.0 + %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264) + %or = or i1 %one.inf, %class + ret i1 %or +} + +define i1 @class_normal_or_fcmp_one_zero(half %x) { +; CHECK-LABEL: @class_normal_or_fcmp_one_zero( +; CHECK-NEXT: [[ONE_INF:%.*]] = fcmp one half [[X:%.*]], 0xH0000 +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264) +; CHECK-NEXT: [[OR:%.*]] = or i1 [[ONE_INF]], [[CLASS]] +; CHECK-NEXT: ret i1 [[OR]] +; + %one.inf = fcmp one half %x, 0.0 + %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264) + %or = or i1 %one.inf, %class + ret i1 %or +} + +define i1 @fcmp_une_zero_or_class_normal(half %x) { +; CHECK-LABEL: @fcmp_une_zero_or_class_normal( +; CHECK-NEXT: [[UNE_INF:%.*]] = fcmp une half [[X:%.*]], 0xH0000 +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264) +; CHECK-NEXT: [[OR:%.*]] = or i1 [[UNE_INF]], [[CLASS]] +; CHECK-NEXT: ret i1 [[OR]] +; + %une.inf = fcmp une half %x, 0.0 + %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264) + %or = or i1 %une.inf, %class + ret i1 %or +} + +define i1 @class_normal_or_fcmp_une_zero(half %x) { +; CHECK-LABEL: @class_normal_or_fcmp_une_zero( +; CHECK-NEXT: [[UNE_INF:%.*]] = fcmp une half [[X:%.*]], 0xH0000 +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264) +; CHECK-NEXT: [[OR:%.*]] = or i1 [[UNE_INF]], [[CLASS]] +; CHECK-NEXT: ret i1 [[OR]] +; + %une.inf = fcmp une half %x, 0.0 + %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264) + %or = or i1 %une.inf, %class + ret i1 %or +} + +define i1 @fcmp_oeq_inf_xor_class_normal(half %x) { +; CHECK-LABEL: @fcmp_oeq_inf_xor_class_normal( +; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00 +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264) +; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[OEQ_INF]], [[CLASS]] +; CHECK-NEXT: ret i1 [[XOR]] +; + %oeq.inf = fcmp oeq half %x, 0xH7C00 + %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264) + %xor = xor i1 %oeq.inf, %class + ret i1 %xor +} + +define i1 @class_normal_xor_fcmp_oeq_inf(half %x) { +; CHECK-LABEL: @class_normal_xor_fcmp_oeq_inf( +; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00 +; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X]], i32 264) +; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[CLASS]], [[OEQ_INF]] +; CHECK-NEXT: ret i1 [[XOR]] +; + %oeq.inf = fcmp oeq half %x, 0xH7C00 + %class = call i1 @llvm.is.fpclass.f16(half %x, i32 264) + %xor = xor i1 %class, %oeq.inf + ret i1 %xor +} + + +declare half @llvm.fabs.f16(half) #0 +declare half @llvm.canonicalize.f16(half) #0 +declare <2 x half> @llvm.fabs.v2f16(<2 x half>) #0 +declare i1 @llvm.is.fpclass.f16(half, i32 immarg) #0 +declare <2 x i1> @llvm.is.fpclass.v2f16(<2 x half>, i32 immarg) #0 + +attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }