| ; 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: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 776) |
| ; CHECK-NEXT: ret i1 [[CLASS]] |
| ; |
| %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: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 776) |
| ; CHECK-NEXT: ret i1 [[CLASS]] |
| ; |
| %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: [[CLASS:%.*]] = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> [[X:%.*]], i32 776) |
| ; CHECK-NEXT: ret <2 x i1> [[CLASS]] |
| ; |
| %oeq.inf = fcmp oeq <2 x half> %x, <half 0xH7C00, half 0xH7C00> |
| %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: ret i1 true |
| ; |
| %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:%.*]] = fcmp uno half [[Y:%.*]], 0xH0000 |
| ; 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: ret i1 false |
| ; |
| %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: ret i1 true |
| ; |
| %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: ret i1 false |
| ; |
| %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: [[SUBNORMAL_CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 144) |
| ; CHECK-NEXT: ret i1 [[SUBNORMAL_CLASS]] |
| ; |
| %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: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) |
| ; CHECK-NEXT: [[SUBNORMAL_CLASS:%.*]] = fcmp one half [[TMP1]], 0xH7C00 |
| ; CHECK-NEXT: ret i1 [[SUBNORMAL_CLASS]] |
| ; |
| %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: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) |
| ; CHECK-NEXT: [[OR:%.*]] = fcmp one half [[TMP1]], 0xH7C00 |
| ; 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: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]]) |
| ; CHECK-NEXT: [[OR:%.*]] = fcmp one half [[TMP1]], 0xH7C00 |
| ; 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: [[AND:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 240) |
| ; 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: [[OR:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 756) |
| ; 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: [[TMP1:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]]) |
| ; CHECK-NEXT: [[OR:%.*]] = fcmp one <2 x half> [[TMP1]], <half 0xH7C00, half 0xH7C00> |
| ; 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, <half 0xH0400, half 0xH0400> |
| %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: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 360) |
| ; CHECK-NEXT: ret i1 [[CLASS]] |
| ; |
| %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_oeq_zero_or_class_normal_daz(half %x) #1 { |
| ; CHECK-LABEL: @fcmp_oeq_zero_or_class_normal_daz( |
| ; 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 <2 x i1> @fcmp_oeq_zero_or_class_normal_daz_v2f16(<2 x half> %x) #1 { |
| ; CHECK-LABEL: @fcmp_oeq_zero_or_class_normal_daz_v2f16( |
| ; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq <2 x half> [[X:%.*]], zeroinitializer |
| ; 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, zeroinitializer |
| %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_zero_or_class_normal_dynamic(half %x) #2 { |
| ; CHECK-LABEL: @fcmp_oeq_zero_or_class_normal_dynamic( |
| ; 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 <2 x i1> @fcmp_oeq_zero_or_class_normal_dynamic_v2f16(<2 x half> %x) #2 { |
| ; CHECK-LABEL: @fcmp_oeq_zero_or_class_normal_dynamic_v2f16( |
| ; CHECK-NEXT: [[OEQ_INF:%.*]] = fcmp oeq <2 x half> [[X:%.*]], zeroinitializer |
| ; 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, zeroinitializer |
| %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 @class_normal_or_fcmp_oeq_zero(half %x) { |
| ; CHECK-LABEL: @class_normal_or_fcmp_oeq_zero( |
| ; CHECK-NEXT: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 360) |
| ; CHECK-NEXT: ret i1 [[CLASS]] |
| ; |
| %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: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 363) |
| ; CHECK-NEXT: ret i1 [[CLASS]] |
| ; |
| %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: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 363) |
| ; CHECK-NEXT: ret i1 [[CLASS]] |
| ; |
| %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: [[CLASS:%.*]] = fcmp one half [[X:%.*]], 0xH0000 |
| ; CHECK-NEXT: ret i1 [[CLASS]] |
| ; |
| %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_one_zero_or_class_normal_daz(half %x) #1 { |
| ; CHECK-LABEL: @fcmp_one_zero_or_class_normal_daz( |
| ; 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_one_zero_or_class_normal_dynamic(half %x) #2 { |
| ; CHECK-LABEL: @fcmp_one_zero_or_class_normal_dynamic( |
| ; 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: [[CLASS:%.*]] = fcmp one half [[X:%.*]], 0xH0000 |
| ; CHECK-NEXT: ret i1 [[CLASS]] |
| ; |
| %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: [[CLASS:%.*]] = fcmp une half [[X:%.*]], 0xH0000 |
| ; CHECK-NEXT: ret i1 [[CLASS]] |
| ; |
| %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: [[CLASS:%.*]] = fcmp une half [[X:%.*]], 0xH0000 |
| ; CHECK-NEXT: ret i1 [[CLASS]] |
| ; |
| %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_daz(half %x) #1 { |
| ; CHECK-LABEL: @class_normal_or_fcmp_une_zero_daz( |
| ; 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_dynamic(half %x) #2 { |
| ; CHECK-LABEL: @class_normal_or_fcmp_une_zero_dynamic( |
| ; 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: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 776) |
| ; CHECK-NEXT: ret i1 [[CLASS]] |
| ; |
| %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: [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 776) |
| ; CHECK-NEXT: ret i1 [[CLASS]] |
| ; |
| %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) } |
| attributes #1 = { "denormal-fp-math"="ieee,preserve-sign" } |
| attributes #2 = { "denormal-fp-math"="ieee,dynamic" } |