mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-10 18:34:09 +00:00
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:
parent
e8c92dd439
commit
2808ccb775
@ -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);
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user