[llvm] ea067b7 - InstCombine: Add baseline tests for and (fcmp ord x), (fcmp u* x)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 19 04:48:54 PST 2022


Author: Matt Arsenault
Date: 2022-12-19T07:48:49-05:00
New Revision: ea067b70ea7a5a2842852ed6b04ef9f4e0dfe907

URL: https://github.com/llvm/llvm-project/commit/ea067b70ea7a5a2842852ed6b04ef9f4e0dfe907
DIFF: https://github.com/llvm/llvm-project/commit/ea067b70ea7a5a2842852ed6b04ef9f4e0dfe907.diff

LOG: InstCombine: Add baseline tests for and (fcmp ord x), (fcmp u* x)

Added: 
    llvm/test/Transforms/InstCombine/unordered-compare-and-ordered.ll

Modified: 
    

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/InstCombine/unordered-compare-and-ordered.ll b/llvm/test/Transforms/InstCombine/unordered-compare-and-ordered.ll
new file mode 100644
index 000000000000..36d7eb9ea70a
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/unordered-compare-and-ordered.ll
@@ -0,0 +1,502 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -passes=instcombine < %s | FileCheck %s
+
+define i1 @fcmp_ord_and_uno(half %x, half %y) {
+; CHECK-LABEL: @fcmp_ord_and_uno(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT:    [[UNO:%.*]] = fcmp uno half [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UNO]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %ord = fcmp ord half %x, 0.0
+  %uno = fcmp uno half %x, %y
+  %and = and i1 %ord, %uno
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_and_ueq(half %x, half %y) {
+; CHECK-LABEL: @fcmp_ord_and_ueq(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %ord = fcmp ord half %x, 0.0
+  %ueq = fcmp ueq half %x, %y
+  %and = and i1 %ord, %ueq
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_and_ugt(half %x, half %y) {
+; CHECK-LABEL: @fcmp_ord_and_ugt(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT:    [[UGT:%.*]] = fcmp ugt half [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UGT]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %ord = fcmp ord half %x, 0.0
+  %ugt = fcmp ugt half %x, %y
+  %and = and i1 %ord, %ugt
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_and_uge(half %x, half %y) {
+; CHECK-LABEL: @fcmp_ord_and_uge(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT:    [[UGE:%.*]] = fcmp uge half [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UGE]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %ord = fcmp ord half %x, 0.0
+  %uge = fcmp uge half %x, %y
+  %and = and i1 %ord, %uge
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_and_ult(half %x, half %y) {
+; CHECK-LABEL: @fcmp_ord_and_ult(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT:    [[ULT:%.*]] = fcmp ult half [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[ULT]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %ord = fcmp ord half %x, 0.0
+  %ult = fcmp ult half %x, %y
+  %and = and i1 %ord, %ult
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_and_ule(half %x, half %y) {
+; CHECK-LABEL: @fcmp_ord_and_ule(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT:    [[ULE:%.*]] = fcmp ule half [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[ULE]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %ord = fcmp ord half %x, 0.0
+  %ule = fcmp ule half %x, %y
+  %and = and i1 %ord, %ule
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_and_une(half %x, half %y) {
+; CHECK-LABEL: @fcmp_ord_and_une(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT:    [[UNE:%.*]] = fcmp une half [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UNE]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %ord = fcmp ord half %x, 0.0
+  %une = fcmp une half %x, %y
+  %and = and i1 %ord, %une
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_and_true(half %x, half %y) {
+; CHECK-LABEL: @fcmp_ord_and_true(
+; CHECK-NEXT:    [[UNE:%.*]] = fcmp une half [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[UNE]]
+;
+  %ord = fcmp true half %x, 0.0
+  %une = fcmp une half %x, %y
+  %and = and i1 %ord, %une
+  ret i1 %and
+}
+
+define <2 x i1> @fcmp_ord_and_ueq_vector(<2 x half> %x, <2 x half> %y) {
+; CHECK-LABEL: @fcmp_ord_and_ueq_vector(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord <2 x half> [[X:%.*]], zeroinitializer
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq <2 x half> [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and <2 x i1> [[ORD]], [[UEQ]]
+; CHECK-NEXT:    ret <2 x i1> [[AND]]
+;
+  %ord = fcmp ord <2 x half> %x, zeroinitializer
+  %ueq = fcmp ueq <2 x half> %x, %y
+  %and = and <2 x i1> %ord, %ueq
+  ret <2 x i1> %and
+}
+
+; Negative test
+define i1 @fcmp_ord_and_ueq_
diff erent_value0(half %x, half %y, half %z) {
+; CHECK-LABEL: @fcmp_ord_and_ueq_
diff erent_value0(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[Z:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %ord = fcmp ord half %x, 0.0
+  %ueq = fcmp ueq half %z, %y
+  %and = and i1 %ord, %ueq
+  ret i1 %and
+}
+
+; Negative test
+define i1 @fcmp_ord_and_ueq_
diff erent_value1(half %x, half %y, half %z) {
+; CHECK-LABEL: @fcmp_ord_and_ueq_
diff erent_value1(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[Y:%.*]], [[Z:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %ord = fcmp ord half %x, 0.0
+  %ueq = fcmp ueq half %y, %z
+  %and = and i1 %ord, %ueq
+  ret i1 %and
+}
+
+declare half @foo()
+
+define i1 @fcmp_ord_and_ueq_commute0() {
+; CHECK-LABEL: @fcmp_ord_and_ueq_commute0(
+; CHECK-NEXT:    [[X:%.*]] = call half @foo()
+; CHECK-NEXT:    [[Y:%.*]] = call half @foo()
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[UEQ]], [[ORD]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %x = call half @foo()
+  %y = call half @foo()
+  %ord = fcmp ord half %x, 0.0
+  %ueq = fcmp ueq half %x, %y
+  %and = and i1 %ueq, %ord
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_and_ueq_commute1() {
+; CHECK-LABEL: @fcmp_ord_and_ueq_commute1(
+; CHECK-NEXT:    [[X:%.*]] = call half @foo()
+; CHECK-NEXT:    [[Y:%.*]] = call half @foo()
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %x = call half @foo()
+  %y = call half @foo()
+  %ord = fcmp ord half %x, 0.0
+  %ueq = fcmp ueq half %x, %y
+  %and = and i1 %ord, %ueq
+  ret i1 %and
+}
+
+define i1 @fcmp_oeq_x_x_and_ult(half %x, half %y) {
+; CHECK-LABEL: @fcmp_oeq_x_x_and_ult(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT:    [[ULT:%.*]] = fcmp ult half [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[ULT]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %ord = fcmp oeq half %x, %x ; noncanonical ordered
+  %ult = fcmp ult half %x, %y
+  %and = and i1 %ord, %ult
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_and_ueq_preserve_flags(half %x, half %y) {
+; CHECK-LABEL: @fcmp_ord_and_ueq_preserve_flags(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp nsz ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp nsz ueq half [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %ord = fcmp nsz ord half %x, 0.0
+  %ueq = fcmp nsz ueq half %x, %y
+  %and = and i1 %ord, %ueq
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_and_ueq_preserve_subset_flags0(half %x, half %y) {
+; CHECK-LABEL: @fcmp_ord_and_ueq_preserve_subset_flags0(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp nsz ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ninf nsz ueq half [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %ord = fcmp nsz ord half %x, 0.0
+  %ueq = fcmp ninf nsz ueq half %x, %y
+  %and = and i1 %ord, %ueq
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_and_ueq_preserve_subset_flags1(half %x, half %y) {
+; CHECK-LABEL: @fcmp_ord_and_ueq_preserve_subset_flags1(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ninf nsz ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp nsz ueq half [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %ord = fcmp ninf nsz ord half %x, 0.0
+  %ueq = fcmp nsz ueq half %x, %y
+  %and = and i1 %ord, %ueq
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_and_ueq_flags_lhs(half %x, half %y) {
+; CHECK-LABEL: @fcmp_ord_and_ueq_flags_lhs(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp nsz ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %ord = fcmp nsz ord half %x, 0.0
+  %ueq = fcmp ueq half %x, %y
+  %and = and i1 %ord, %ueq
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_and_ueq_flags_rhs(half %x, half %y) {
+; CHECK-LABEL: @fcmp_ord_and_ueq_flags_rhs(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp nsz ueq half [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %ord = fcmp ord half %x, 0.0
+  %ueq = fcmp nsz ueq half %x, %y
+  %and = and i1 %ord, %ueq
+  ret i1 %and
+}
+
+; Can ignore fabs and fneg
+define i1 @fcmp_ord_and_fabs_ueq(half %x, half %y) {
+; CHECK-LABEL: @fcmp_ord_and_fabs_ueq(
+; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[FABS_X]], [[Y:%.*]]
+; 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 ueq half %fabs.x, %y
+  %and = and i1 %ord, %ueq
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_fabs_and_ueq(half %x, half %y) {
+; CHECK-LABEL: @fcmp_ord_fabs_and_ueq(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y:%.*]]
+; 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 ueq half %x, %y
+  %and = and i1 %ord, %ueq
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_and_fabs_ueq_commute0() {
+; CHECK-LABEL: @fcmp_ord_and_fabs_ueq_commute0(
+; CHECK-NEXT:    [[X:%.*]] = call half @foo()
+; CHECK-NEXT:    [[Y:%.*]] = call half @foo()
+; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X]])
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[Y]], [[FABS_X]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %x = call half @foo()
+  %y = call half @foo()
+  %fabs.x = call half @llvm.fabs.f16(half %x)
+  %ord = fcmp ord half %x, 0.0
+  %ueq = fcmp ueq half %y, %fabs.x
+  %and = and i1 %ord, %ueq
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_and_fabs_ueq_commute1() {
+; CHECK-LABEL: @fcmp_ord_and_fabs_ueq_commute1(
+; CHECK-NEXT:    [[X:%.*]] = call half @foo()
+; CHECK-NEXT:    [[Y:%.*]] = call half @foo()
+; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X]])
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[Y]], [[FABS_X]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[UEQ]], [[ORD]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %x = call half @foo()
+  %y = call half @foo()
+  %fabs.x = call half @llvm.fabs.f16(half %x)
+  %ord = fcmp ord half %x, 0.0
+  %ueq = fcmp ueq half %y, %fabs.x
+  %and = and i1 %ueq, %ord
+  ret i1 %and
+}
+
+define <2 x i1> @fcmp_ord_and_fabs_ueq_vector(<2 x half> %x, <2 x half> %y) {
+; CHECK-LABEL: @fcmp_ord_and_fabs_ueq_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:    [[UEQ:%.*]] = fcmp ueq <2 x half> [[FABS_X]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and <2 x i1> [[ORD]], [[UEQ]]
+; 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> %x, zeroinitializer
+  %ueq = fcmp ueq <2 x half> %fabs.x, %y
+  %and = and <2 x i1> %ord, %ueq
+  ret <2 x i1> %and
+}
+
+define i1 @fcmp_ord_fabs_and_fabs_ueq(half %x, half %y) {
+; CHECK-LABEL: @fcmp_ord_fabs_and_fabs_ueq(
+; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[FABS_X]], [[Y:%.*]]
+; 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 ueq half %fabs.x, %y
+  %and = and i1 %ord, %ueq
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_and_fneg_ueq(half %x, half %y) {
+; CHECK-LABEL: @fcmp_ord_and_fneg_ueq(
+; CHECK-NEXT:    [[FNEG_X:%.*]] = fneg half [[X:%.*]]
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[FNEG_X]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %fneg.x = fneg half %x
+  %ord = fcmp ord half %x, 0.0
+  %ueq = fcmp ueq half %fneg.x, %y
+  %and = and i1 %ord, %ueq
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_fneg_and_ueq(half %x, half %y) {
+; CHECK-LABEL: @fcmp_ord_fneg_and_ueq(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X:%.*]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %fneg.x = fneg half %x
+  %ord = fcmp ord half %fneg.x, 0.0
+  %ueq = fcmp ueq half %x, %y
+  %and = and i1 %ord, %ueq
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_fneg_and_fneg_ueq(half %x, half %y) {
+; CHECK-LABEL: @fcmp_ord_fneg_and_fneg_ueq(
+; CHECK-NEXT:    [[FNEG_X:%.*]] = fneg half [[X:%.*]]
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[FNEG_X]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %fneg.x = fneg half %x
+  %ord = fcmp ord half %fneg.x, 0.0
+  %ueq = fcmp ueq half %fneg.x, %y
+  %and = and i1 %ord, %ueq
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_and_fneg_fabs_ueq(half %x, half %y) {
+; CHECK-LABEL: @fcmp_ord_and_fneg_fabs_ueq(
+; CHECK-NEXT:    [[FABS_X:%.*]] = call half @llvm.fabs.f16(half [[X:%.*]])
+; CHECK-NEXT:    [[FNEG_FABS_X:%.*]] = fneg half [[FABS_X]]
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[FNEG_FABS_X]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %fabs.x = call half @llvm.fabs.f16(half %x)
+  %fneg.fabs.x = fneg half %fabs.x
+  %ord = fcmp ord half %x, 0.0
+  %ueq = fcmp ueq half %fneg.fabs.x, %y
+  %and = and i1 %ord, %ueq
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_and_copysign_ueq(half %x, half %y, half %z) {
+; CHECK-LABEL: @fcmp_ord_and_copysign_ueq(
+; CHECK-NEXT:    [[COPYSIGN_X_Y:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Z:%.*]])
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[COPYSIGN_X_Y]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %copysign.x.y = call half @llvm.copysign.f16(half %x, half %z)
+  %ord = fcmp ord half %x, 0.0
+  %ueq = fcmp ueq half %copysign.x.y, %y
+  %and = and i1 %ord, %ueq
+  ret i1 %and
+}
+
+define i1 @fcmp_copysign_ord_and_ueq(half %x, half %y, half %z) {
+; CHECK-LABEL: @fcmp_copysign_ord_and_ueq(
+; CHECK-NEXT:    [[COPYSIGN_X_Y:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Z:%.*]])
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[COPYSIGN_X_Y]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %copysign.x.y = call half @llvm.copysign.f16(half %x, half %z)
+  %ord = fcmp ord half %copysign.x.y, 0.0
+  %ueq = fcmp ueq half %x, %y
+  %and = and i1 %ord, %ueq
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_and_copysign_ueq_commute(half %x, half %y, half %z) {
+; CHECK-LABEL: @fcmp_ord_and_copysign_ueq_commute(
+; CHECK-NEXT:    [[COPYSIGN_X_Y:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Z:%.*]])
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[COPYSIGN_X_Y]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %copysign.x.y = call half @llvm.copysign.f16(half %x, half %z)
+  %ord = fcmp ord half %x, 0.0
+  %ueq = fcmp ueq half %y, %copysign.x.y
+  %and = and i1 %ord, %ueq
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_and_copysign_fneg_ueq(half %x, half %y, half %z) {
+; CHECK-LABEL: @fcmp_ord_and_copysign_fneg_ueq(
+; CHECK-NEXT:    [[COPYSIGN_X_Y:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Z:%.*]])
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[COPYSIGN_X_Y]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %x.fneg = fneg half %x
+  %copysign.x.y = call half @llvm.copysign.f16(half %x.fneg, half %z)
+  %ord = fcmp ord half %x, 0.0
+  %ueq = fcmp ueq half %copysign.x.y, %y
+  %and = and i1 %ord, %ueq
+  ret i1 %and
+}
+
+define i1 @fcmp_ord_and_fneg_copysign_ueq(half %x, half %y, half %z) {
+; CHECK-LABEL: @fcmp_ord_and_fneg_copysign_ueq(
+; CHECK-NEXT:    [[COPYSIGN_X_Y:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[Z:%.*]])
+; CHECK-NEXT:    [[FNEG_COPYSIGN:%.*]] = fneg half [[COPYSIGN_X_Y]]
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord half [[X]], 0xH0000
+; CHECK-NEXT:    [[UEQ:%.*]] = fcmp ueq half [[FNEG_COPYSIGN]], [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[ORD]], [[UEQ]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %copysign.x.y = call half @llvm.copysign.f16(half %x, half %z)
+  %fneg.copysign = fneg half %copysign.x.y
+  %ord = fcmp ord half %x, 0.0
+  %ueq = fcmp ueq half %fneg.copysign, %y
+  %and = and i1 %ord, %ueq
+  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)
+declare <2 x half> @llvm.copysign.v2f16(<2 x half>, <2 x half>)


        


More information about the llvm-commits mailing list