diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 70 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86IntrinsicsInfo.h | 90 |
2 files changed, 53 insertions, 107 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 663857def13..82a726b7313 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -17503,30 +17503,66 @@ static SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, const X86Subtarget &Subtarget ISD::CondCode CC = (ISD::CondCode)IntrData->Opc1; SDValue LHS = Op.getOperand(1); SDValue RHS = Op.getOperand(2); - unsigned X86CC = TranslateX86CC(CC, dl, true, LHS, RHS, DAG); - assert(X86CC != X86::COND_INVALID && "Unexpected illegal condition!"); - SDValue Cond = DAG.getNode(IntrData->Opc0, dl, MVT::i32, LHS, RHS); - SDValue SetCC = DAG.getNode(X86ISD::SETCC, dl, MVT::i8, - DAG.getConstant(X86CC, dl, MVT::i8), Cond); + SDValue Comi = DAG.getNode(IntrData->Opc0, dl, MVT::i32, LHS, RHS); + SDValue InvComi = DAG.getNode(IntrData->Opc0, dl, MVT::i32, RHS, LHS); + SDValue SetCC; + switch (CC) { + case ISD::SETEQ: { // (ZF = 0 and PF = 0) + SetCC = DAG.getNode(X86ISD::SETCC, dl, MVT::i8, + DAG.getConstant(X86::COND_E, dl, MVT::i8), Comi); + SDValue SetNP = DAG.getNode(X86ISD::SETCC, dl, MVT::i8, + DAG.getConstant(X86::COND_NP, dl, MVT::i8), + Comi); + SetCC = DAG.getNode(ISD::AND, dl, MVT::i8, SetCC, SetNP); + break; + } + case ISD::SETNE: { // (ZF = 1 or PF = 1) + SetCC = DAG.getNode(X86ISD::SETCC, dl, MVT::i8, + DAG.getConstant(X86::COND_NE, dl, MVT::i8), Comi); + SDValue SetP = DAG.getNode(X86ISD::SETCC, dl, MVT::i8, + DAG.getConstant(X86::COND_P, dl, MVT::i8), + Comi); + SetCC = DAG.getNode(ISD::OR, dl, MVT::i8, SetCC, SetP); + break; + } + case ISD::SETGT: // (CF = 0 and ZF = 0) + SetCC = DAG.getNode(X86ISD::SETCC, dl, MVT::i8, + DAG.getConstant(X86::COND_A, dl, MVT::i8), Comi); + break; + case ISD::SETLT: { // The condition is opposite to GT. Swap the operands. + SetCC = DAG.getNode(X86ISD::SETCC, dl, MVT::i8, + DAG.getConstant(X86::COND_A, dl, MVT::i8), InvComi); + break; + } + case ISD::SETGE: // CF = 0 + SetCC = DAG.getNode(X86ISD::SETCC, dl, MVT::i8, + DAG.getConstant(X86::COND_AE, dl, MVT::i8), Comi); + break; + case ISD::SETLE: // The condition is opposite to GE. Swap the operands. + SetCC = DAG.getNode(X86ISD::SETCC, dl, MVT::i8, + DAG.getConstant(X86::COND_AE, dl, MVT::i8), InvComi); + break; + default: + llvm_unreachable("Unexpected illegal condition!"); + } return DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, SetCC); } case COMI_RM: { // Comparison intrinsics with Sae SDValue LHS = Op.getOperand(1); SDValue RHS = Op.getOperand(2); - SDValue CC = Op.getOperand(3); + unsigned CondVal = cast<ConstantSDNode>(Op.getOperand(3))->getZExtValue(); SDValue Sae = Op.getOperand(4); - auto ComiType = TranslateX86ConstCondToX86CC(CC); - // choose between ordered and unordered (comi/ucomi) - unsigned comiOp = std::get<0>(ComiType) ? IntrData->Opc0 : IntrData->Opc1; - SDValue Cond; - if (cast<ConstantSDNode>(Sae)->getZExtValue() != - X86::STATIC_ROUNDING::CUR_DIRECTION) - Cond = DAG.getNode(comiOp, dl, MVT::i32, LHS, RHS, Sae); + + SDValue FCmp; + if (cast<ConstantSDNode>(Sae)->getZExtValue() == + X86::STATIC_ROUNDING::CUR_DIRECTION) + FCmp = DAG.getNode(X86ISD::FSETCC, dl, MVT::i1, LHS, RHS, + DAG.getConstant(CondVal, dl, MVT::i8)); else - Cond = DAG.getNode(comiOp, dl, MVT::i32, LHS, RHS); - SDValue SetCC = DAG.getNode(X86ISD::SETCC, dl, MVT::i8, - DAG.getConstant(std::get<1>(ComiType), dl, MVT::i8), Cond); - return DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, SetCC); + FCmp = DAG.getNode(X86ISD::FSETCC, dl, MVT::i1, LHS, RHS, + DAG.getConstant(CondVal, dl, MVT::i8), Sae); + // AnyExt just uses KMOVW %kreg, %r32; ZeroExt emits "and $1, %reg" + return DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, FCmp); } case VSHIFT: return getTargetVShiftNode(IntrData->Opc0, dl, Op.getSimpleValueType(), diff --git a/llvm/lib/Target/X86/X86IntrinsicsInfo.h b/llvm/lib/Target/X86/X86IntrinsicsInfo.h index 8764cb3b5ab..5fbc61010c7 100644 --- a/llvm/lib/Target/X86/X86IntrinsicsInfo.h +++ b/llvm/lib/Target/X86/X86IntrinsicsInfo.h @@ -2331,96 +2331,6 @@ static void verifyIntrinsicTables() { std::end(IntrinsicsWithChain)) && "Intrinsic data tables should have unique entries"); } - -// X86 specific compare constants. -// They must be kept in synch with avxintrin.h -#define _X86_CMP_EQ_OQ 0x00 /* Equal (ordered, non-signaling) */ -#define _X86_CMP_LT_OS 0x01 /* Less-than (ordered, signaling) */ -#define _X86_CMP_LE_OS 0x02 /* Less-than-or-equal (ordered, signaling) */ -#define _X86_CMP_UNORD_Q 0x03 /* Unordered (non-signaling) */ -#define _X86_CMP_NEQ_UQ 0x04 /* Not-equal (unordered, non-signaling) */ -#define _X86_CMP_NLT_US 0x05 /* Not-less-than (unordered, signaling) */ -#define _X86_CMP_NLE_US 0x06 /* Not-less-than-or-equal (unordered, signaling) */ -#define _X86_CMP_ORD_Q 0x07 /* Ordered (nonsignaling) */ -#define _X86_CMP_EQ_UQ 0x08 /* Equal (unordered, non-signaling) */ -#define _X86_CMP_NGE_US 0x09 /* Not-greater-than-or-equal (unord, signaling) */ -#define _X86_CMP_NGT_US 0x0a /* Not-greater-than (unordered, signaling) */ -#define _X86_CMP_FALSE_OQ 0x0b /* False (ordered, non-signaling) */ -#define _X86_CMP_NEQ_OQ 0x0c /* Not-equal (ordered, non-signaling) */ -#define _X86_CMP_GE_OS 0x0d /* Greater-than-or-equal (ordered, signaling) */ -#define _X86_CMP_GT_OS 0x0e /* Greater-than (ordered, signaling) */ -#define _X86_CMP_TRUE_UQ 0x0f /* True (unordered, non-signaling) */ -#define _X86_CMP_EQ_OS 0x10 /* Equal (ordered, signaling) */ -#define _X86_CMP_LT_OQ 0x11 /* Less-than (ordered, non-signaling) */ -#define _X86_CMP_LE_OQ 0x12 /* Less-than-or-equal (ordered, non-signaling) */ -#define _X86_CMP_UNORD_S 0x13 /* Unordered (signaling) */ -#define _X86_CMP_NEQ_US 0x14 /* Not-equal (unordered, signaling) */ -#define _X86_CMP_NLT_UQ 0x15 /* Not-less-than (unordered, non-signaling) */ -#define _X86_CMP_NLE_UQ 0x16 /* Not-less-than-or-equal (unord, non-signaling) */ -#define _X86_CMP_ORD_S 0x17 /* Ordered (signaling) */ -#define _X86_CMP_EQ_US 0x18 /* Equal (unordered, signaling) */ -#define _X86_CMP_NGE_UQ 0x19 /* Not-greater-than-or-equal (unord, non-sign) */ -#define _X86_CMP_NGT_UQ 0x1a /* Not-greater-than (unordered, non-signaling) */ -#define _X86_CMP_FALSE_OS 0x1b /* False (ordered, signaling) */ -#define _X86_CMP_NEQ_OS 0x1c /* Not-equal (ordered, signaling) */ -#define _X86_CMP_GE_OQ 0x1d /* Greater-than-or-equal (ordered, non-signaling) */ -#define _X86_CMP_GT_OQ 0x1e /* Greater-than (ordered, non-signaling) */ -#define _X86_CMP_TRUE_US 0x1f /* True (unordered, signaling) */ - -/* -* Get comparison modifier from _mm_comi_round_sd/ss intrinsic -* Return tuple <isOrdered, X86 condcode> -*/ -static std::tuple<bool,unsigned> TranslateX86ConstCondToX86CC(SDValue &imm) { - ConstantSDNode *CImm = dyn_cast<ConstantSDNode>(imm); - unsigned IntImm = CImm->getZExtValue(); - // On a floating point condition, the flags are set as follows: - // ZF PF CF op - // 0 | 0 | 0 | X > Y - // 0 | 0 | 1 | X < Y - // 1 | 0 | 0 | X == Y - // 1 | 1 | 1 | unordered - switch (IntImm) { - default: llvm_unreachable("Invalid floating point compare value for Comi!"); - case _X86_CMP_EQ_OQ: // 0x00 - Equal (ordered, nonsignaling) - case _X86_CMP_EQ_OS: // 0x10 - Equal (ordered, signaling) - return std::make_tuple(true, X86::COND_E); - case _X86_CMP_EQ_UQ: // 0x08 - Equal (unordered, non-signaling) - case _X86_CMP_EQ_US: // 0x18 - Equal (unordered, signaling) - return std::make_tuple(false , X86::COND_E); - case _X86_CMP_LT_OS: // 0x01 - Less-than (ordered, signaling) - case _X86_CMP_LT_OQ: // 0x11 - Less-than (ordered, nonsignaling) - return std::make_tuple(true, X86::COND_B); - case _X86_CMP_NGE_US: // 0x09 - Not-greater-than-or-equal (unordered, signaling) - case _X86_CMP_NGE_UQ: // 0x19 - Not-greater-than-or-equal (unordered, nonsignaling) - return std::make_tuple(false , X86::COND_B); - case _X86_CMP_LE_OS: // 0x02 - Less-than-or-equal (ordered, signaling) - case _X86_CMP_LE_OQ: // 0x12 - Less-than-or-equal (ordered, nonsignaling) - return std::make_tuple(true, X86::COND_BE); - case _X86_CMP_NGT_US: // 0x0A - Not-greater-than (unordered, signaling) - case _X86_CMP_NGT_UQ: // 0x1A - Not-greater-than (unordered, nonsignaling) - return std::make_tuple(false, X86::COND_BE); - case _X86_CMP_GT_OS: // 0x0E - Greater-than (ordered, signaling) - case _X86_CMP_GT_OQ: // 0x1E - Greater-than (ordered, nonsignaling) - return std::make_tuple(true, X86::COND_A); - case _X86_CMP_NLE_US: // 0x06 - Not-less-than-or-equal (unordered,signaling) - case _X86_CMP_NLE_UQ: // 0x16 - Not-less-than-or-equal (unordered, nonsignaling) - return std::make_tuple(false, X86::COND_A); - case _X86_CMP_GE_OS: // 0x0D - Greater-than-or-equal (ordered, signaling) - case _X86_CMP_GE_OQ: // 0x1D - Greater-than-or-equal (ordered, nonsignaling) - return std::make_tuple(true, X86::COND_AE); - case _X86_CMP_NLT_US: // 0x05 - Not-less-than (unordered, signaling) - case _X86_CMP_NLT_UQ: // 0x15 - Not-less-than (unordered, nonsignaling) - return std::make_tuple(false, X86::COND_AE); - case _X86_CMP_NEQ_OQ: // 0x0C - Not-equal (ordered, non-signaling) - case _X86_CMP_NEQ_OS: // 0x1C - Not-equal (ordered, signaling) - return std::make_tuple(true, X86::COND_NE); - case _X86_CMP_NEQ_UQ: // 0x04 - Not-equal (unordered, nonsignaling) - case _X86_CMP_NEQ_US: // 0x14 - Not-equal (unordered, signaling) - return std::make_tuple(false, X86::COND_NE); - } -} - } // End llvm namespace #endif |