forked from OSchip/llvm-project
[X86] Split X86ISD::CMP into an integer and FP opcode.
This commit is contained in:
parent
af20211944
commit
d26f11108b
|
@ -5008,7 +5008,7 @@ void X86DAGToDAGISel::Select(SDNode *Node) {
|
|||
return;
|
||||
}
|
||||
|
||||
case X86ISD::CMP:
|
||||
case X86ISD::FCMP:
|
||||
case X86ISD::STRICT_FCMP:
|
||||
case X86ISD::STRICT_FCMPS: {
|
||||
bool IsStrictCmp = Node->getOpcode() == X86ISD::STRICT_FCMP ||
|
||||
|
@ -5020,71 +5020,76 @@ void X86DAGToDAGISel::Select(SDNode *Node) {
|
|||
MVT CmpVT = N0.getSimpleValueType();
|
||||
|
||||
// Floating point needs special handling if we don't have FCOMI.
|
||||
// FIXME: Should we have a X86ISD::FCMP to avoid mixing int and fp?
|
||||
if (CmpVT.isFloatingPoint()) {
|
||||
if (Subtarget->hasCMov())
|
||||
break;
|
||||
if (Subtarget->hasCMov())
|
||||
break;
|
||||
|
||||
bool IsSignaling = Node->getOpcode() == X86ISD::STRICT_FCMPS;
|
||||
bool IsSignaling = Node->getOpcode() == X86ISD::STRICT_FCMPS;
|
||||
|
||||
unsigned Opc;
|
||||
switch (CmpVT.SimpleTy) {
|
||||
default: llvm_unreachable("Unexpected type!");
|
||||
case MVT::f32:
|
||||
Opc = IsSignaling ? X86::COM_Fpr32 : X86::UCOM_Fpr32;
|
||||
break;
|
||||
case MVT::f64:
|
||||
Opc = IsSignaling ? X86::COM_Fpr64 : X86::UCOM_Fpr64;
|
||||
break;
|
||||
case MVT::f80:
|
||||
Opc = IsSignaling ? X86::COM_Fpr80 : X86::UCOM_Fpr80;
|
||||
break;
|
||||
}
|
||||
|
||||
SDValue Cmp;
|
||||
SDValue Chain =
|
||||
IsStrictCmp ? Node->getOperand(0) : CurDAG->getEntryNode();
|
||||
if (IsStrictCmp) {
|
||||
SDVTList VTs = CurDAG->getVTList(MVT::i16, MVT::Other);
|
||||
Cmp = SDValue(CurDAG->getMachineNode(Opc, dl, VTs, {N0, N1, Chain}), 0);
|
||||
Chain = Cmp.getValue(1);
|
||||
} else {
|
||||
Cmp = SDValue(CurDAG->getMachineNode(Opc, dl, MVT::i16, N0, N1), 0);
|
||||
}
|
||||
|
||||
// Move FPSW to AX.
|
||||
SDValue FPSW = CurDAG->getCopyToReg(Chain, dl, X86::FPSW, Cmp, SDValue());
|
||||
Chain = FPSW;
|
||||
SDValue FNSTSW =
|
||||
SDValue(CurDAG->getMachineNode(X86::FNSTSW16r, dl, MVT::i16, FPSW,
|
||||
FPSW.getValue(1)),
|
||||
0);
|
||||
|
||||
// Extract upper 8-bits of AX.
|
||||
SDValue Extract =
|
||||
CurDAG->getTargetExtractSubreg(X86::sub_8bit_hi, dl, MVT::i8, FNSTSW);
|
||||
|
||||
// Move AH into flags.
|
||||
// Some 64-bit targets lack SAHF support, but they do support FCOMI.
|
||||
assert(Subtarget->hasLAHFSAHF() &&
|
||||
"Target doesn't support SAHF or FCOMI?");
|
||||
SDValue AH = CurDAG->getCopyToReg(Chain, dl, X86::AH, Extract, SDValue());
|
||||
Chain = AH;
|
||||
SDValue SAHF = SDValue(
|
||||
CurDAG->getMachineNode(X86::SAHF, dl, MVT::i32, AH.getValue(1)), 0);
|
||||
|
||||
if (IsStrictCmp)
|
||||
ReplaceUses(SDValue(Node, 1), Chain);
|
||||
|
||||
ReplaceUses(SDValue(Node, 0), SAHF);
|
||||
CurDAG->RemoveDeadNode(Node);
|
||||
return;
|
||||
unsigned Opc;
|
||||
switch (CmpVT.SimpleTy) {
|
||||
default: llvm_unreachable("Unexpected type!");
|
||||
case MVT::f32:
|
||||
Opc = IsSignaling ? X86::COM_Fpr32 : X86::UCOM_Fpr32;
|
||||
break;
|
||||
case MVT::f64:
|
||||
Opc = IsSignaling ? X86::COM_Fpr64 : X86::UCOM_Fpr64;
|
||||
break;
|
||||
case MVT::f80:
|
||||
Opc = IsSignaling ? X86::COM_Fpr80 : X86::UCOM_Fpr80;
|
||||
break;
|
||||
}
|
||||
|
||||
SDValue Cmp;
|
||||
SDValue Chain =
|
||||
IsStrictCmp ? Node->getOperand(0) : CurDAG->getEntryNode();
|
||||
if (IsStrictCmp) {
|
||||
SDVTList VTs = CurDAG->getVTList(MVT::i16, MVT::Other);
|
||||
Cmp = SDValue(CurDAG->getMachineNode(Opc, dl, VTs, {N0, N1, Chain}), 0);
|
||||
Chain = Cmp.getValue(1);
|
||||
} else {
|
||||
Cmp = SDValue(CurDAG->getMachineNode(Opc, dl, MVT::i16, N0, N1), 0);
|
||||
}
|
||||
|
||||
// Move FPSW to AX.
|
||||
SDValue FPSW = CurDAG->getCopyToReg(Chain, dl, X86::FPSW, Cmp, SDValue());
|
||||
Chain = FPSW;
|
||||
SDValue FNSTSW =
|
||||
SDValue(CurDAG->getMachineNode(X86::FNSTSW16r, dl, MVT::i16, FPSW,
|
||||
FPSW.getValue(1)),
|
||||
0);
|
||||
|
||||
// Extract upper 8-bits of AX.
|
||||
SDValue Extract =
|
||||
CurDAG->getTargetExtractSubreg(X86::sub_8bit_hi, dl, MVT::i8, FNSTSW);
|
||||
|
||||
// Move AH into flags.
|
||||
// Some 64-bit targets lack SAHF support, but they do support FCOMI.
|
||||
assert(Subtarget->hasLAHFSAHF() &&
|
||||
"Target doesn't support SAHF or FCOMI?");
|
||||
SDValue AH = CurDAG->getCopyToReg(Chain, dl, X86::AH, Extract, SDValue());
|
||||
Chain = AH;
|
||||
SDValue SAHF = SDValue(
|
||||
CurDAG->getMachineNode(X86::SAHF, dl, MVT::i32, AH.getValue(1)), 0);
|
||||
|
||||
if (IsStrictCmp)
|
||||
ReplaceUses(SDValue(Node, 1), Chain);
|
||||
|
||||
ReplaceUses(SDValue(Node, 0), SAHF);
|
||||
CurDAG->RemoveDeadNode(Node);
|
||||
return;
|
||||
}
|
||||
|
||||
case X86ISD::CMP: {
|
||||
SDValue N0 = Node->getOperand(0);
|
||||
SDValue N1 = Node->getOperand(1);
|
||||
|
||||
// Optimizations for TEST compares.
|
||||
if (!isNullConstant(N1))
|
||||
break;
|
||||
|
||||
// Save the original VT of the compare.
|
||||
MVT CmpVT = N0.getSimpleValueType();
|
||||
|
||||
// If we are comparing (and (shr X, C, Mask) with 0, emit a BEXTR followed
|
||||
// by a test instruction. The test should be removed later by
|
||||
// analyzeCompare if we are using only the zero flag.
|
||||
|
|
|
@ -21169,7 +21169,7 @@ static std::pair<SDValue, SDValue> EmitCmp(SDValue Op0, SDValue Op1,
|
|||
dl, {MVT::i32, MVT::Other}, {Chain, Op0, Op1});
|
||||
return std::make_pair(Res, Res.getValue(1));
|
||||
}
|
||||
return std::make_pair(DAG.getNode(X86ISD::CMP, dl, MVT::i32, Op0, Op1),
|
||||
return std::make_pair(DAG.getNode(X86ISD::FCMP, dl, MVT::i32, Op0, Op1),
|
||||
SDValue());
|
||||
}
|
||||
|
||||
|
@ -22344,7 +22344,8 @@ static SDValue LowerXALUO(SDValue Op, SelectionDAG &DAG) {
|
|||
/// Return true if opcode is a X86 logical comparison.
|
||||
static bool isX86LogicalCmp(SDValue Op) {
|
||||
unsigned Opc = Op.getOpcode();
|
||||
if (Opc == X86ISD::CMP || Opc == X86ISD::COMI || Opc == X86ISD::UCOMI)
|
||||
if (Opc == X86ISD::CMP || Opc == X86ISD::COMI || Opc == X86ISD::UCOMI ||
|
||||
Opc == X86ISD::FCMP)
|
||||
return true;
|
||||
if (Op.getResNo() == 1 &&
|
||||
(Opc == X86ISD::ADD || Opc == X86ISD::SUB || Opc == X86ISD::ADC ||
|
||||
|
@ -23295,7 +23296,7 @@ SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
|
|||
(void)NewBR;
|
||||
Dest = FalseBB;
|
||||
|
||||
SDValue Cmp = DAG.getNode(X86ISD::CMP, dl, MVT::i32,
|
||||
SDValue Cmp = DAG.getNode(X86ISD::FCMP, dl, MVT::i32,
|
||||
Cond.getOperand(0), Cond.getOperand(1));
|
||||
CC = DAG.getTargetConstant(X86::COND_NE, dl, MVT::i8);
|
||||
Chain = DAG.getNode(X86ISD::BRCOND, dl, Op.getValueType(),
|
||||
|
@ -23310,7 +23311,7 @@ SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
|
|||
// For FCMP_UNE, we can emit
|
||||
// two branches instead of an explicit OR instruction with a
|
||||
// separate test.
|
||||
SDValue Cmp = DAG.getNode(X86ISD::CMP, dl, MVT::i32,
|
||||
SDValue Cmp = DAG.getNode(X86ISD::FCMP, dl, MVT::i32,
|
||||
Cond.getOperand(0), Cond.getOperand(1));
|
||||
CC = DAG.getTargetConstant(X86::COND_NE, dl, MVT::i8);
|
||||
Chain = DAG.getNode(X86ISD::BRCOND, dl, Op.getValueType(),
|
||||
|
@ -29947,6 +29948,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
|
|||
NODE_NAME_CASE(CALL)
|
||||
NODE_NAME_CASE(BT)
|
||||
NODE_NAME_CASE(CMP)
|
||||
NODE_NAME_CASE(FCMP)
|
||||
NODE_NAME_CASE(STRICT_FCMP)
|
||||
NODE_NAME_CASE(STRICT_FCMPS)
|
||||
NODE_NAME_CASE(COMI)
|
||||
|
@ -40372,7 +40374,7 @@ static SDValue combineCompareEqual(SDNode *N, SelectionDAG &DAG,
|
|||
SDLoc DL(N);
|
||||
|
||||
// The SETCCs should both refer to the same CMP.
|
||||
if (CMP0.getOpcode() != X86ISD::CMP || CMP0 != CMP1)
|
||||
if (CMP0.getOpcode() != X86ISD::FCMP || CMP0 != CMP1)
|
||||
return SDValue();
|
||||
|
||||
SDValue CMP00 = CMP0->getOperand(0);
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace llvm {
|
|||
NT_CALL,
|
||||
|
||||
/// X86 compare and logical compare instructions.
|
||||
CMP, COMI, UCOMI,
|
||||
CMP, FCMP, COMI, UCOMI,
|
||||
|
||||
/// X86 bit-test instructions.
|
||||
BT,
|
||||
|
|
|
@ -59,9 +59,9 @@ def X86fhadd : SDNode<"X86ISD::FHADD", SDTFPBinOp>;
|
|||
def X86fhsub : SDNode<"X86ISD::FHSUB", SDTFPBinOp>;
|
||||
def X86hadd : SDNode<"X86ISD::HADD", SDTIntBinOp>;
|
||||
def X86hsub : SDNode<"X86ISD::HSUB", SDTIntBinOp>;
|
||||
def X86comi : SDNode<"X86ISD::COMI", SDTX86CmpTest>;
|
||||
def X86ucomi : SDNode<"X86ISD::UCOMI", SDTX86CmpTest>;
|
||||
def X86cmps : SDNode<"X86ISD::FSETCC", SDTX86Cmps>;
|
||||
def X86comi : SDNode<"X86ISD::COMI", SDTX86FCmp>;
|
||||
def X86ucomi : SDNode<"X86ISD::UCOMI", SDTX86FCmp>;
|
||||
def X86cmps : SDNode<"X86ISD::FSETCC", SDTX86Cmps>;
|
||||
def X86pshufb : SDNode<"X86ISD::PSHUFB",
|
||||
SDTypeProfile<1, 2, [SDTCVecEltisVT<0, i8>, SDTCisSameAs<0,1>,
|
||||
SDTCisSameAs<0,2>]>>;
|
||||
|
|
|
@ -16,7 +16,10 @@
|
|||
// X86 specific DAG Nodes.
|
||||
//
|
||||
|
||||
def SDTX86CmpTest : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisSameAs<1, 2>]>;
|
||||
def SDTX86CmpTest : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisInt<1>,
|
||||
SDTCisSameAs<1, 2>]>;
|
||||
def SDTX86FCmp : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisFP<1>,
|
||||
SDTCisSameAs<1, 2>]>;
|
||||
|
||||
def SDTX86Cmps : SDTypeProfile<1, 3, [SDTCisFP<0>, SDTCisSameAs<1, 2>, SDTCisVT<3, i8>]>;
|
||||
//def SDTX86Cmpss : SDTypeProfile<1, 3, [SDTCisVT<0, f32>, SDTCisSameAs<1, 2>, SDTCisVT<3, i8>]>;
|
||||
|
@ -144,8 +147,9 @@ def X86shld : SDNode<"X86ISD::SHLD", SDTIntShiftDOp>;
|
|||
def X86shrd : SDNode<"X86ISD::SHRD", SDTIntShiftDOp>;
|
||||
|
||||
def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest>;
|
||||
def X86strict_fcmp : SDNode<"X86ISD::STRICT_FCMP", SDTX86CmpTest, [SDNPHasChain]>;
|
||||
def X86strict_fcmps : SDNode<"X86ISD::STRICT_FCMPS", SDTX86CmpTest, [SDNPHasChain]>;
|
||||
def X86fcmp : SDNode<"X86ISD::FCMP", SDTX86FCmp>;
|
||||
def X86strict_fcmp : SDNode<"X86ISD::STRICT_FCMP", SDTX86FCmp, [SDNPHasChain]>;
|
||||
def X86strict_fcmps : SDNode<"X86ISD::STRICT_FCMPS", SDTX86FCmp, [SDNPHasChain]>;
|
||||
def X86bt : SDNode<"X86ISD::BT", SDTX86CmpTest>;
|
||||
|
||||
def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov>;
|
||||
|
@ -382,7 +386,7 @@ class X86VMemOperand<RegisterClass RC, string printMethod,
|
|||
def anymem : X86MemOperand<"printanymem">;
|
||||
def X86any_fcmp : PatFrags<(ops node:$lhs, node:$rhs),
|
||||
[(X86strict_fcmp node:$lhs, node:$rhs),
|
||||
(X86cmp node:$lhs, node:$rhs)]>;
|
||||
(X86fcmp node:$lhs, node:$rhs)]>;
|
||||
|
||||
// FIXME: Right now we allow any size during parsing, but we might want to
|
||||
// restrict to only unsized memory.
|
||||
|
|
Loading…
Reference in New Issue