summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2010-04-23 18:21:16 +0000
committerEvan Cheng <evan.cheng@apple.com>2010-04-23 18:21:16 +0000
commit2808ccb77515d049bfeb44fdf1228ccf9f034f2f (patch)
treeab6ab7384c0f23a825afadc6815aaee2ca87e58d /lib
parente8c92dd439581bec7e3516cbdbea74e2e60fe7f0 (diff)
downloadllvm-2808ccb77515d049bfeb44fdf1228ccf9f034f2f.tar.gz
llvm-2808ccb77515d049bfeb44fdf1228ccf9f034f2f.tar.bz2
llvm-2808ccb77515d049bfeb44fdf1228ccf9f034f2f.tar.xz
Fix X86ISD::CMP i16 to i32 promotion.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@102192 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp56
-rw-r--r--lib/Target/X86/X86ISelLowering.h5
2 files changed, 48 insertions, 13 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 203a589ab6..b8fc7e6612 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -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);
diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h
index 00d63960ef..7996184f33 100644
--- a/lib/Target/X86/X86ISelLowering.h
+++ b/lib/Target/X86/X86ISelLowering.h
@@ -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;
};