Fix X86ISD::CMP i16 to i32 promotion.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@102192 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2010-04-23 18:21:16 +00:00
parent e8c92dd439
commit 2808ccb775
2 changed files with 48 additions and 13 deletions

View File

@ -5887,10 +5887,33 @@ SDValue X86TargetLowering::LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const {
return DAG.getNode(X86ISD::FOR, dl, VT, Val, SignBit);
}
// getSetCCPromoteOpcode - Return the opcode that should be used to promote
// operands of a setcc. FIXME: See DAGTypeLegalizer::PromoteSetCCOperands.
static unsigned getSetCCPromoteOpcode(ISD::CondCode CC) {
switch (CC) {
default: return 0;
case ISD::SETEQ:
case ISD::SETNE:
case ISD::SETUGE:
case ISD::SETUGT:
case ISD::SETULE:
case ISD::SETULT:
// ALL of these operations will work if we either sign or zero extend
// the operands (including the unsigned comparisons!). Zero extend is
// usually a simpler/cheaper operation, so prefer it.
return ISD::ZERO_EXTEND;
case ISD::SETGE:
case ISD::SETGT:
case ISD::SETLT:
case ISD::SETLE:
return ISD::SIGN_EXTEND;
}
}
/// Emit nodes that will be selected as "test Op0,Op0", or something
/// equivalent.
SDValue X86TargetLowering::EmitTest(SDValue Op, unsigned X86CC,
SelectionDAG &DAG) const {
ISD::CondCode CC, SelectionDAG &DAG) const {
DebugLoc dl = Op.getDebugLoc();
// CF and OF aren't always set the way we want. Determine which
@ -6014,8 +6037,13 @@ SDValue X86TargetLowering::EmitTest(SDValue Op, unsigned X86CC,
}
// Otherwise just emit a CMP with 0, which is the TEST pattern.
if (Subtarget->shouldPromote16Bit() && Op.getValueType() == MVT::i16)
Op = DAG.getNode(ISD::ANY_EXTEND, Op.getDebugLoc(), MVT::i32, Op);
EVT PVT;
if (Subtarget->shouldPromote16Bit() && Op.getValueType() == MVT::i16 &&
(isa<ConstantSDNode>(Op) || IsDesirableToPromoteOp(Op, PVT))) {
unsigned POpc = getSetCCPromoteOpcode(CC);
if (POpc)
Op = DAG.getNode(POpc, Op.getDebugLoc(), MVT::i32, Op);
}
return DAG.getNode(X86ISD::CMP, dl, MVT::i32, Op,
DAG.getConstant(0, Op.getValueType()));
}
@ -6023,15 +6051,21 @@ SDValue X86TargetLowering::EmitTest(SDValue Op, unsigned X86CC,
/// Emit nodes that will be selected as "cmp Op0,Op1", or something
/// equivalent.
SDValue X86TargetLowering::EmitCmp(SDValue Op0, SDValue Op1, unsigned X86CC,
SelectionDAG &DAG) const {
ISD::CondCode CC, SelectionDAG &DAG) const {
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op1))
if (C->getAPIntValue() == 0)
return EmitTest(Op0, X86CC, DAG);
return EmitTest(Op0, X86CC, CC, DAG);
DebugLoc dl = Op0.getDebugLoc();
if (Subtarget->shouldPromote16Bit() && Op0.getValueType() == MVT::i16) {
Op0 = DAG.getNode(ISD::ANY_EXTEND, Op0.getDebugLoc(), MVT::i32, Op0);
Op1 = DAG.getNode(ISD::ANY_EXTEND, Op1.getDebugLoc(), MVT::i32, Op1);
EVT PVT;
if (Subtarget->shouldPromote16Bit() && Op0.getValueType() == MVT::i16 &&
(isa<ConstantSDNode>(Op0) || IsDesirableToPromoteOp(Op0, PVT)) &&
(isa<ConstantSDNode>(Op1) || IsDesirableToPromoteOp(Op1, PVT))) {
unsigned POpc = getSetCCPromoteOpcode(CC);
if (POpc) {
Op0 = DAG.getNode(POpc, Op0.getDebugLoc(), MVT::i32, Op0);
Op1 = DAG.getNode(POpc, Op1.getDebugLoc(), MVT::i32, Op1);
}
}
return DAG.getNode(X86ISD::CMP, dl, MVT::i32, Op0, Op1);
}
@ -6134,7 +6168,7 @@ SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
if (X86CC == X86::COND_INVALID)
return SDValue();
SDValue Cond = EmitCmp(Op0, Op1, X86CC, DAG);
SDValue Cond = EmitCmp(Op0, Op1, X86CC, CC, DAG);
// Use sbb x, x to materialize carry bit into a GPR.
if (X86CC == X86::COND_B)
@ -6367,7 +6401,7 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
if (addTest) {
CC = DAG.getConstant(X86::COND_NE, MVT::i8);
Cond = EmitTest(Cond, X86::COND_NE, DAG);
Cond = EmitTest(Cond, X86::COND_NE, ISD::SETNE, DAG);
}
// X86ISD::CMOV means set the result (which is operand 1) to the RHS if
@ -6541,7 +6575,7 @@ SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
if (addTest) {
CC = DAG.getConstant(X86::COND_NE, MVT::i8);
Cond = EmitTest(Cond, X86::COND_NE, DAG);
Cond = EmitTest(Cond, X86::COND_NE, ISD::SETNE, DAG);
}
return DAG.getNode(X86ISD::BRCOND, dl, Op.getValueType(),
Chain, Dest, CC, Cond);

View File

@ -815,11 +815,12 @@ namespace llvm {
/// Emit nodes that will be selected as "test Op0,Op0", or something
/// equivalent, for use with the given x86 condition code.
SDValue EmitTest(SDValue Op0, unsigned X86CC, SelectionDAG &DAG) const;
SDValue EmitTest(SDValue Op0, unsigned X86CC, ISD::CondCode CC,
SelectionDAG &DAG) const;
/// Emit nodes that will be selected as "cmp Op0,Op1", or something
/// equivalent, for use with the given x86 condition code.
SDValue EmitCmp(SDValue Op0, SDValue Op1, unsigned X86CC,
SDValue EmitCmp(SDValue Op0, SDValue Op1, unsigned X86CC, ISD::CondCode CC,
SelectionDAG &DAG) const;
};