; 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_different_value0(half %x, half %y, half %z) { ; CHECK-LABEL: @fcmp_ord_and_ueq_different_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_different_value1(half %x, half %y, half %z) { ; CHECK-LABEL: @fcmp_ord_and_ueq_different_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: [[TMP1:%.*]] = fneg half [[Z:%.*]] ; CHECK-NEXT: [[FNEG_COPYSIGN:%.*]] = call half @llvm.copysign.f16(half [[X:%.*]], half [[TMP1]]) ; 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>)