Index: lib/CodeGen/SelectionDAG/TargetLowering.cpp =================================================================== --- lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -115,6 +115,7 @@ } + /// SoftenSetCCOperands - Soften the operands of a comparison. This code is /// shared among BR_CC, SELECT_CC, and SETCC handlers. void TargetLowering::softenSetCCOperands(SelectionDAG &DAG, EVT VT, @@ -126,6 +127,7 @@ // Expand into one or more soft-fp libcall(s). RTLIB::Libcall LC1 = RTLIB::UNKNOWN_LIBCALL, LC2 = RTLIB::UNKNOWN_LIBCALL; + bool getInverseCC = false; switch (CCCode) { case ISD::SETEQ: case ISD::SETOEQ: @@ -165,35 +167,39 @@ LC1 = (VT == MVT::f32) ? RTLIB::O_F32 : (VT == MVT::f64) ? RTLIB::O_F64 : RTLIB::O_F128; break; - default: + case ISD::SETONE: + // SETONE = SETOLT | SETOGT + LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 : + (VT == MVT::f64) ? RTLIB::OLT_F64 : RTLIB::OLT_F128; + LC2 = (VT == MVT::f32) ? RTLIB::OGT_F32 : + (VT == MVT::f64) ? RTLIB::OGT_F64 : RTLIB::OGT_F128; + break; + case ISD::SETUEQ: LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 : (VT == MVT::f64) ? RTLIB::UO_F64 : RTLIB::UO_F128; + LC2 = (VT == MVT::f32) ? RTLIB::OEQ_F32 : + (VT == MVT::f64) ? RTLIB::OEQ_F64 : RTLIB::OEQ_F128; + break; + default: + // Inverse CC for unordered comparison + getInverseCC = true; switch (CCCode) { - case ISD::SETONE: - // SETONE = SETOLT | SETOGT - LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 : - (VT == MVT::f64) ? RTLIB::OLT_F64 : RTLIB::OLT_F128; - // Fallthrough - case ISD::SETUGT: - LC2 = (VT == MVT::f32) ? RTLIB::OGT_F32 : - (VT == MVT::f64) ? RTLIB::OGT_F64 : RTLIB::OGT_F128; - break; - case ISD::SETUGE: - LC2 = (VT == MVT::f32) ? RTLIB::OGE_F32 : - (VT == MVT::f64) ? RTLIB::OGE_F64 : RTLIB::OGE_F128; - break; case ISD::SETULT: - LC2 = (VT == MVT::f32) ? RTLIB::OLT_F32 : - (VT == MVT::f64) ? RTLIB::OLT_F64 : RTLIB::OLT_F128; - break; + LC1 = (VT == MVT::f32) ? RTLIB::OGE_F32 : + (VT == MVT::f64) ? RTLIB::OGE_F64 : RTLIB::OGE_F128; + break; case ISD::SETULE: - LC2 = (VT == MVT::f32) ? RTLIB::OLE_F32 : + LC1 = (VT == MVT::f32) ? RTLIB::OGT_F32 : + (VT == MVT::f64) ? RTLIB::OGT_F64 : RTLIB::OGT_F128; + break; + case ISD::SETUGT: + LC1 = (VT == MVT::f32) ? RTLIB::OLE_F32 : (VT == MVT::f64) ? RTLIB::OLE_F64 : RTLIB::OLE_F128; - break; - case ISD::SETUEQ: - LC2 = (VT == MVT::f32) ? RTLIB::OEQ_F32 : - (VT == MVT::f64) ? RTLIB::OEQ_F64 : RTLIB::OEQ_F128; - break; + break; + case ISD::SETUGE: + LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 : + (VT == MVT::f64) ? RTLIB::OLT_F64 : RTLIB::OLT_F128; + break; default: llvm_unreachable("Do not know how to soften this setcc!"); } } @@ -202,20 +208,24 @@ EVT RetVT = getCmpLibcallReturnType(); SDValue Ops[2] = { NewLHS, NewRHS }; NewLHS = makeLibCall(DAG, LC1, RetVT, Ops, 2, false/*sign irrelevant*/, - dl).first; + dl).first; NewRHS = DAG.getConstant(0, dl, RetVT); + CCCode = getCmpLibcallCC(LC1); + if (getInverseCC) + CCCode = getSetCCInverse(CCCode, true); + if (LC2 != RTLIB::UNKNOWN_LIBCALL) { - SDValue Tmp = DAG.getNode(ISD::SETCC, dl, - getSetCCResultType(*DAG.getContext(), RetVT), - NewLHS, NewRHS, DAG.getCondCode(CCCode)); - NewLHS = makeLibCall(DAG, LC2, RetVT, Ops, 2, false/*sign irrelevant*/, - dl).first; - NewLHS = DAG.getNode(ISD::SETCC, dl, - getSetCCResultType(*DAG.getContext(), RetVT), NewLHS, - NewRHS, DAG.getCondCode(getCmpLibcallCC(LC2))); - NewLHS = DAG.getNode(ISD::OR, dl, Tmp.getValueType(), Tmp, NewLHS); - NewRHS = SDValue(); + SDValue Tmp = DAG.getNode(ISD::SETCC, dl, + getSetCCResultType(*DAG.getContext(), RetVT), + NewLHS, NewRHS, DAG.getCondCode(CCCode)); + NewLHS = makeLibCall(DAG, LC2, RetVT, Ops, 2, false/*sign irrelevant*/, + dl).first; + NewLHS = DAG.getNode(ISD::SETCC, dl, + getSetCCResultType(*DAG.getContext(), RetVT), NewLHS, + NewRHS, DAG.getCondCode(getCmpLibcallCC(LC2))); + NewLHS = DAG.getNode(ISD::OR, dl, Tmp.getValueType(), Tmp, NewLHS); + NewRHS = SDValue(); } } Index: test/CodeGen/AArch64/arm64-fp128.ll =================================================================== --- test/CodeGen/AArch64/arm64-fp128.ll +++ test/CodeGen/AArch64/arm64-fp128.ll @@ -148,15 +148,10 @@ ; CHECK: ldr q1, [{{x[0-9]+}}, :lo12:rhs] %val = fcmp ugt fp128 %lhs, %rhs -; CHECK: bl __gttf2 +; CHECK: bl __letf2 ; CHECK: cmp w0, #0 ; CHECK: cset [[GT:w[0-9]+]], gt -; CHECK: bl __unordtf2 -; CHECK: cmp w0, #0 -; CHECK: cset [[UNORDERED:w[0-9]+]], ne -; CHECK: orr w0, [[UNORDERED]], [[GT]] - ret i1 %val ; CHECK: ret } @@ -171,29 +166,19 @@ ; olt == !uge, which LLVM unfortunately "optimizes" this to. %cond = fcmp olt fp128 %lhs, %rhs -; CHECK: bl __getf2 -; CHECK: cmp w0, #0 -; CHECK: cset [[OGE:w[0-9]+]], ge - -; CHECK: bl __unordtf2 +; CHECK: bl __lttf2 ; CHECK: cmp w0, #0 -; CHECK: cset [[UNORDERED:w[0-9]+]], ne - -; CHECK: orr [[UGE:w[0-9]+]], [[UNORDERED]], [[OGE]] -; CHECK: cbnz [[UGE]], [[RET29:.LBB[0-9]+_[0-9]+]] +; CHECK-NEXT: b.ge [[IFFALSE:.LBB[0-9]+_[0-9]+]] br i1 %cond, label %iftrue, label %iffalse iftrue: ret i32 42 ; CHECK-NEXT: BB# ; CHECK-NEXT: movz w0, #0x2a -; CHECK-NEXT: b [[REALRET:.LBB[0-9]+_[0-9]+]] - +; CHECK: ret iffalse: ret i32 29 -; CHECK: [[RET29]]: -; CHECK-NEXT: movz w0, #0x1d -; CHECK-NEXT: [[REALRET]]: +; CHECK: movz w0, #0x1d ; CHECK: ret } Index: test/CodeGen/Mips/mips16fpe.ll =================================================================== --- test/CodeGen/Mips/mips16fpe.ll +++ test/CodeGen/Mips/mips16fpe.ll @@ -297,7 +297,7 @@ %and2 = and i1 %lnot, %cmp1 %and = zext i1 %and2 to i32 store i32 %and, i32* @ltsf2_result, align 4 -;16hf: lw ${{[0-9]+}}, %call16(__mips16_unordsf2)(${{[0-9]+}}) +;16hf: lw ${{[0-9]+}}, %call16(__mips16_ltsf2)(${{[0-9]+}}) ;16hf: lw ${{[0-9]+}}, %call16(__mips16_ltsf2)(${{[0-9]+}}) ret void } @@ -313,7 +313,7 @@ %and2 = and i1 %lnot, %cmp1 %and = zext i1 %and2 to i32 store i32 %and, i32* @ltdf2_result, align 4 -;16hf: lw ${{[0-9]+}}, %call16(__mips16_unorddf2)(${{[0-9]+}}) +;16hf: lw ${{[0-9]+}}, %call16(__mips16_ltdf2)(${{[0-9]+}}) ;16hf: lw ${{[0-9]+}}, %call16(__mips16_ltdf2)(${{[0-9]+}}) ret void } Index: test/CodeGen/Thumb2/float-cmp.ll =================================================================== --- test/CodeGen/Thumb2/float-cmp.ll +++ test/CodeGen/Thumb2/float-cmp.ll @@ -81,8 +81,7 @@ } define i1 @cmp_f_ugt(float %a, float %b) { ; CHECK-LABEL: cmp_f_ugt: -; NONE: bl __aeabi_fcmpgt -; NONE: bl __aeabi_fcmpun +; NONE: bl __aeabi_fcmple ; HARD: vcmpe.f32 ; HARD: movhi r0, #1 %1 = fcmp ugt float %a, %b @@ -90,8 +89,7 @@ } define i1 @cmp_f_uge(float %a, float %b) { ; CHECK-LABEL: cmp_f_uge: -; NONE: bl __aeabi_fcmpge -; NONE: bl __aeabi_fcmpun +; NONE: bl __aeabi_fcmplt ; HARD: vcmpe.f32 ; HARD: movpl r0, #1 %1 = fcmp uge float %a, %b @@ -99,8 +97,7 @@ } define i1 @cmp_f_ult(float %a, float %b) { ; CHECK-LABEL: cmp_f_ult: -; NONE: bl __aeabi_fcmplt -; NONE: bl __aeabi_fcmpun +; NONE: bl __aeabi_fcmpge ; HARD: vcmpe.f32 ; HARD: movlt r0, #1 %1 = fcmp ult float %a, %b @@ -108,8 +105,7 @@ } define i1 @cmp_f_ule(float %a, float %b) { ; CHECK-LABEL: cmp_f_ule: -; NONE: bl __aeabi_fcmple -; NONE: bl __aeabi_fcmpun +; NONE: bl __aeabi_fcmpgt ; HARD: vcmpe.f32 ; HARD: movle r0, #1 %1 = fcmp ule float %a, %b @@ -214,10 +210,8 @@ } define i1 @cmp_d_ugt(double %a, double %b) { ; CHECK-LABEL: cmp_d_ugt: -; NONE: bl __aeabi_dcmpgt -; NONE: bl __aeabi_dcmpun -; SP: bl __aeabi_dcmpgt -; SP: bl __aeabi_dcmpun +; NONE: bl __aeabi_dcmple +; SP: bl __aeabi_dcmple ; DP: vcmpe.f64 ; DP: movhi r0, #1 %1 = fcmp ugt double %a, %b @@ -226,10 +220,8 @@ define i1 @cmp_d_ult(double %a, double %b) { ; CHECK-LABEL: cmp_d_ult: -; NONE: bl __aeabi_dcmplt -; NONE: bl __aeabi_dcmpun -; SP: bl __aeabi_dcmplt -; SP: bl __aeabi_dcmpun +; NONE: bl __aeabi_dcmpge +; SP: bl __aeabi_dcmpge ; DP: vcmpe.f64 ; DP: movlt r0, #1 %1 = fcmp ult double %a, %b @@ -268,10 +260,8 @@ define i1 @cmp_d_uge(double %a, double %b) { ; CHECK-LABEL: cmp_d_uge: -; NONE: bl __aeabi_dcmpge -; NONE: bl __aeabi_dcmpun -; SP: bl __aeabi_dcmpge -; SP: bl __aeabi_dcmpun +; NONE: bl __aeabi_dcmplt +; SP: bl __aeabi_dcmplt ; DP: vcmpe.f64 ; DP: movpl r0, #1 %1 = fcmp uge double %a, %b @@ -280,10 +270,8 @@ define i1 @cmp_d_ule(double %a, double %b) { ; CHECK-LABEL: cmp_d_ule: -; NONE: bl __aeabi_dcmple -; NONE: bl __aeabi_dcmpun -; SP: bl __aeabi_dcmple -; SP: bl __aeabi_dcmpun +; NONE: bl __aeabi_dcmpgt +; SP: bl __aeabi_dcmpgt ; DP: vcmpe.f64 ; DP: movle r0, #1 %1 = fcmp ule double %a, %b Index: test/CodeGen/Thumb2/float-intrinsics-double.ll =================================================================== --- test/CodeGen/Thumb2/float-intrinsics-double.ll +++ test/CodeGen/Thumb2/float-intrinsics-double.ll @@ -109,9 +109,8 @@ define double @abs_d(double %a) { ; CHECK-LABEL: abs_d: ; NONE: bic r1, r1, #-2147483648 -; SP: bl __aeabi_dcmpgt -; SP: bl __aeabi_dcmpun ; SP: bl __aeabi_dsub +; SP: bl __aeabi_dcmple ; DP: vabs.f64 d0, d0 %1 = call double @llvm.fabs.f64(double %a) ret double %1