[X86] Split X86ISD::CMP into an integer and FP opcode.

This commit is contained in:
Craig Topper 2020-02-15 15:20:03 -08:00
parent af20211944
commit d26f11108b
5 changed files with 82 additions and 71 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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,

View File

@ -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>]>>;

View File

@ -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.