[llvm] b421125 - InstCombine: Add baseline test for pattern in clang's isnormal
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 19 04:26:57 PST 2022
Author: Matt Arsenault
Date: 2022-12-19T07:26:52-05:00
New Revision: b421125524a5933a2f315fae90f9408d0c1a8e33
URL: https://github.com/llvm/llvm-project/commit/b421125524a5933a2f315fae90f9408d0c1a8e33
DIFF: https://github.com/llvm/llvm-project/commit/b421125524a5933a2f315fae90f9408d0c1a8e33.diff
LOG: InstCombine: Add baseline test for pattern in clang's isnormal
Clang emits this peculiar pattern as an isfinite check in
__builtin_isnormal which can be simplified. We should fix clang to
emit this in the first place, but should also fold it here.
Added:
Modified:
llvm/test/Transforms/InstCombine/and-fcmp.ll
Removed:
################################################################################
diff --git a/llvm/test/Transforms/InstCombine/and-fcmp.ll b/llvm/test/Transforms/InstCombine/and-fcmp.ll
index f42e705dfe9f..bbd48c23761c 100644
--- a/llvm/test/Transforms/InstCombine/and-fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/and-fcmp.ll
@@ -4608,3 +4608,481 @@ define i1 @intersect_fmf_4(double %a, double %b) {
%retval = and i1 %cmp, %cmp1
ret i1 %retval
}
+
+; Clang used to emit this pattern in __builtin_isnormal
+; https://alive2.llvm.org/ce/z/8sw9vi
+define i1 @clang_builtin_isnormal_inf_check(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check(
+; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT: [[CMP:%.*]] = fcmp uge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[CMP]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp ord half %fabs.x, 0.0
+ %cmp = fcmp uge half %fabs.x, 0xH7C00
+ %and = and i1 %ord, %cmp
+ ret i1 %and
+}
+
+define <2 x i1> @clang_builtin_isnormal_inf_check_vector(<2 x half> %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_vector(
+; CHECK-NEXT: [[FABS_X:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord <2 x half> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = fcmp uge <2 x half> [[FABS_X]], <half 0xH7C00, half 0xH7C00>
+; CHECK-NEXT: [[AND:%.*]] = and <2 x i1> [[ORD]], [[CMP]]
+; CHECK-NEXT: ret <2 x i1> [[AND]]
+;
+ %fabs.x = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)
+ %ord = fcmp ord <2 x half> %fabs.x, zeroinitializer
+ %cmp = fcmp uge <2 x half> %fabs.x, <half 0xH7C00, half 0xH7C00>
+ %and = and <2 x i1> %ord, %cmp
+ ret <2 x i1> %and
+}
+
+define i1 @clang_builtin_isnormal_inf_check_commute(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_commute(
+; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT: [[CMP:%.*]] = fcmp uge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP]], [[ORD]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp ord half %fabs.x, 0.0
+ %cmp = fcmp uge half %fabs.x, 0xH7C00
+ %and = and i1 %cmp, %ord
+ ret i1 %and
+}
+
+define i1 @clang_builtin_isnormal_inf_check_commute_nsz_rhs(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_commute_nsz_rhs(
+; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp nsz ord half [[X]], 0xH0000
+; CHECK-NEXT: [[CMP:%.*]] = fcmp uge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP]], [[ORD]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp nsz ord half %fabs.x, 0.0
+ %cmp = fcmp uge half %fabs.x, 0xH7C00
+ %and = and i1 %cmp, %ord
+ ret i1 %and
+}
+
+define i1 @clang_builtin_isnormal_inf_check_commute_nsz_lhs(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_commute_nsz_lhs(
+; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT: [[CMP:%.*]] = fcmp nsz uge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP]], [[ORD]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp ord half %fabs.x, 0.0
+ %cmp = fcmp nsz uge half %fabs.x, 0xH7C00
+ %and = and i1 %cmp, %ord
+ ret i1 %and
+}
+
+define i1 @clang_builtin_isnormal_inf_check_commute_nofabs_ueq(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_commute_nofabs_ueq(
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq half [[X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP]], [[ORD]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %ord = fcmp ord half %x, 0.0
+ %cmp = fcmp ueq half %x, 0xH7C00
+ %and = and i1 %cmp, %ord
+ ret i1 %and
+}
+
+define i1 @clang_builtin_isnormal_inf_check_commute_nsz(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_commute_nsz(
+; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp nsz ord half [[X]], 0xH0000
+; CHECK-NEXT: [[CMP:%.*]] = fcmp nsz uge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP]], [[ORD]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp nsz ord half %fabs.x, 0.0
+ %cmp = fcmp nsz uge half %fabs.x, 0xH7C00
+ %and = and i1 %cmp, %ord
+ ret i1 %and
+}
+
+; ugt -> ogt
+define i1 @clang_builtin_isnormal_inf_check_ugt(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_ugt(
+; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT: [[CMP:%.*]] = fcmp ugt half [[FABS_X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[CMP]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp ord half %fabs.x, 0.0
+ %cmp = fcmp ugt half %fabs.x, 0xH7C00
+ %and = and i1 %ord, %cmp
+ ret i1 %and
+}
+
+; ult -> olt
+define i1 @clang_builtin_isnormal_inf_check_ult(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_ult(
+; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT: [[CMP:%.*]] = fcmp ult half [[FABS_X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[CMP]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp ord half %fabs.x, 0.0
+ %cmp = fcmp ult half %fabs.x, 0xH7C00
+ %and = and i1 %ord, %cmp
+ ret i1 %and
+}
+
+; ule -> ole
+define i1 @clang_builtin_isnormal_inf_check_ule(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_ule(
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT: ret i1 [[ORD]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp ord half %fabs.x, 0.0
+ %cmp = fcmp ule half %fabs.x, 0xH7C00
+ %and = and i1 %ord, %cmp
+ ret i1 %and
+}
+
+; ueq -> oeq
+define i1 @clang_builtin_isnormal_inf_check_ueq(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_ueq(
+; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq half [[FABS_X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[CMP]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp ord half %fabs.x, 0.0
+ %cmp = fcmp ueq half %fabs.x, 0xH7C00
+ %and = and i1 %ord, %cmp
+ ret i1 %and
+}
+
+; une -> ole
+define i1 @clang_builtin_isnormal_inf_check_une(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_une(
+; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT: [[CMP:%.*]] = fcmp une half [[FABS_X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[CMP]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp ord half %fabs.x, 0.0
+ %cmp = fcmp une half %fabs.x, 0xH7C00
+ %and = and i1 %ord, %cmp
+ ret i1 %and
+}
+
+; uno -> ord
+define i1 @clang_builtin_isnormal_inf_check_uno(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_uno(
+; CHECK-NEXT: ret i1 false
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp ord half %fabs.x, 0.0
+ %cmp = fcmp uno half %fabs.x, 0xH7C00
+ %and = and i1 %ord, %cmp
+ ret i1 %and
+}
+
+; ord -> ord
+define i1 @clang_builtin_isnormal_inf_check_ord(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_ord(
+; CHECK-NEXT: [[CMP:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp ord half %fabs.x, 0.0
+ %cmp = fcmp ord half %fabs.x, 0xH7C00
+ %and = and i1 %ord, %cmp
+ ret i1 %and
+}
+
+define i1 @clang_builtin_isnormal_inf_check_oge(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_oge(
+; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT: [[CMP:%.*]] = fcmp oge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[CMP]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp ord half %fabs.x, 0.0
+ %cmp = fcmp oge half %fabs.x, 0xH7C00
+ %and = and i1 %ord, %cmp
+ ret i1 %and
+}
+
+define i1 @clang_builtin_isnormal_inf_check_olt(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_olt(
+; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT: [[CMP:%.*]] = fcmp olt half [[FABS_X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[CMP]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp ord half %fabs.x, 0.0
+ %cmp = fcmp olt half %fabs.x, 0xH7C00
+ %and = and i1 %ord, %cmp
+ ret i1 %and
+}
+
+define i1 @clang_builtin_isnormal_inf_check_ole(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_ole(
+; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT: [[CMP:%.*]] = fcmp ole half [[FABS_X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[CMP]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp ord half %fabs.x, 0.0
+ %cmp = fcmp ole half %fabs.x, 0xH7C00
+ %and = and i1 %ord, %cmp
+ ret i1 %and
+}
+
+define i1 @clang_builtin_isnormal_inf_check_oeq(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_oeq(
+; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq half [[FABS_X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[CMP]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp ord half %fabs.x, 0.0
+ %cmp = fcmp oeq half %fabs.x, 0xH7C00
+ %and = and i1 %ord, %cmp
+ ret i1 %and
+}
+
+define i1 @clang_builtin_isnormal_inf_check_unnececcary_fabs(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_unnececcary_fabs(
+; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT: [[UEQ:%.*]] = fcmp uge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp ord half %x, 0.0
+ %ueq = fcmp uge half %fabs.x, 0xH7C00
+ %and = and i1 %ord, %ueq
+ ret i1 %and
+}
+
+; Negative test
+define i1 @clang_builtin_isnormal_inf_check_not_ord(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_not_ord(
+; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp uno half [[X]], 0xH0000
+; CHECK-NEXT: [[UEQ:%.*]] = fcmp uge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp uno half %fabs.x, 0.0
+ %ueq = fcmp uge half %fabs.x, 0xH7C00
+ %and = and i1 %ord, %ueq
+ ret i1 %and
+}
+
+define i1 @clang_builtin_isnormal_inf_check_missing_fabs(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_missing_fabs(
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT: [[UEQ:%.*]] = fcmp uge half [[X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp ord half %x, 0.0
+ %ueq = fcmp uge half %x, 0xH7C00
+ %and = and i1 %ord, %ueq
+ ret i1 %and
+}
+
+define i1 @clang_builtin_isnormal_inf_check_neg_inf(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_neg_inf(
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT: ret i1 [[ORD]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp ord half %fabs.x, 0.0
+ %ueq = fcmp uge half %fabs.x, 0xHFC00
+ %and = and i1 %ord, %ueq
+ ret i1 %and
+}
+
+; Negative test
+define i1 @clang_builtin_isnormal_inf_check_not_inf(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_not_inf(
+; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT: [[UEQ:%.*]] = fcmp uge half [[FABS_X]], 0xH7BFF
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp ord half %fabs.x, 0.0
+ %ueq = fcmp uge half %fabs.x, 0xH7BFF
+ %and = and i1 %ord, %ueq
+ ret i1 %and
+}
+
+define i1 @clang_builtin_isnormal_inf_check_nsz_lhs(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_nsz_lhs(
+; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp nsz ord half [[X]], 0xH0000
+; CHECK-NEXT: [[UEQ:%.*]] = fcmp uge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp nsz ord half %fabs.x, 0.0
+ %ueq = fcmp uge half %fabs.x, 0xH7C00
+ %and = and i1 %ord, %ueq
+ ret i1 %and
+}
+
+define i1 @clang_builtin_isnormal_inf_check_nsz_rhs(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_nsz_rhs(
+; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT: [[UEQ:%.*]] = fcmp nsz uge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp ord half %fabs.x, 0.0
+ %ueq = fcmp nsz uge half %fabs.x, 0xH7C00
+ %and = and i1 %ord, %ueq
+ ret i1 %and
+}
+
+define i1 @clang_builtin_isnormal_inf_check_nsz(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_nsz(
+; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp nsz ord half [[X]], 0xH0000
+; CHECK-NEXT: [[UEQ:%.*]] = fcmp nsz uge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp nsz ord half %fabs.x, 0.0
+ %ueq = fcmp nsz uge half %fabs.x, 0xH7C00
+ %and = and i1 %ord, %ueq
+ ret i1 %and
+}
+
+define i1 @clang_builtin_isnormal_inf_check_fneg(half %x) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_fneg(
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT: [[CMP:%.*]] = fcmp uge half [[X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[CMP]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fneg.x = fneg half %x
+ %ord = fcmp ord half %fneg.x, 0.0
+ %cmp = fcmp uge half %x, 0xH7C00
+ %and = and i1 %ord, %cmp
+ ret i1 %and
+}
+
+define i1 @clang_builtin_isnormal_inf_check_copysign(half %x, half %y) {
+; CHECK-LABEL: @clang_builtin_isnormal_inf_check_copysign(
+; CHECK-NEXT: [[COPYSIGN_X:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Y:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT: [[CMP:%.*]] = fcmp uge half [[COPYSIGN_X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[CMP]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %copysign.x = call half @llvm.copysign.f16(half %x, half %y)
+ %ord = fcmp ord half %x, 0.0
+ %cmp = fcmp uge half %copysign.x, 0xH7C00
+ %and = and i1 %ord, %cmp
+ ret i1 %and
+}
+
+define i1 @isnormal_logical_select_0(half %x) {
+; CHECK-LABEL: @isnormal_logical_select_0(
+; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT: [[CMP_INF:%.*]] = fcmp uge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[CMP_INF]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp ord half %fabs.x, 0.0
+ %cmp.inf = fcmp uge half %fabs.x, 0xH7C00
+ %and = select i1 %ord, i1 %cmp.inf, i1 false
+ ret i1 %and
+}
+
+define i1 @isnormal_logical_select_1(half %x) {
+; CHECK-LABEL: @isnormal_logical_select_1(
+; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT: [[CMP_INF:%.*]] = fcmp uge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP_INF]], i1 [[ORD]], i1 false
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp ord half %fabs.x, 0.0
+ %cmp.inf = fcmp uge half %fabs.x, 0xH7C00
+ %and = select i1 %cmp.inf, i1 %ord, i1 false
+ ret i1 %and
+}
+
+define i1 @isnormal_logical_select_0_fmf0(half %x) {
+; CHECK-LABEL: @isnormal_logical_select_0_fmf0(
+; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp reassoc nsz arcp ord half [[X]], 0xH0000
+; CHECK-NEXT: [[CMP_INF:%.*]] = fcmp reassoc nsz arcp uge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[CMP_INF]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp nsz arcp reassoc ord half %fabs.x, 0.0
+ %cmp.inf = fcmp nsz arcp reassoc uge half %fabs.x, 0xH7C00
+ %and = select i1 %ord, i1 %cmp.inf, i1 false
+ ret i1 %and
+}
+
+define i1 @isnormal_logical_select_0_fmf1(half %x) {
+; CHECK-LABEL: @isnormal_logical_select_0_fmf1(
+; CHECK-NEXT: [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT: [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT: [[CMP_INF:%.*]] = fcmp reassoc nsz arcp uge half [[FABS_X]], 0xH7C00
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[ORD]], [[CMP_INF]]
+; CHECK-NEXT: ret i1 [[AND]]
+;
+ %fabs.x = call half @llvm.fabs.f16(half %x)
+ %ord = fcmp ord half %fabs.x, 0.0
+ %cmp.inf = fcmp nsz arcp reassoc uge half %fabs.x, 0xH7C00
+ %and = select i1 %ord, i1 %cmp.inf, i1 false
+ ret i1 %and
+}
+
+declare half @llvm.fabs.f16(half)
+declare <2 x half> @llvm.fabs.v2f16(<2 x half>)
+declare half @llvm.copysign.f16(half, half)
More information about the llvm-commits
mailing list