Fix X86ISD::CMP i16 to i32 promotion.
authorEvan Cheng <evan.cheng@apple.com>
Fri, 23 Apr 2010 18:21:16 +0000 (18:21 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Fri, 23 Apr 2010 18:21:16 +0000 (18:21 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@102192 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86ISelLowering.h

index 203a589ab6827cac08671a7eaebc5bd279d3b5dc..b8fc7e6612548871adec495d5ee24fb01dea875b 100644 (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);
index 00d63960ef04ff38509f65e107df33dcaaf91bc3..7996184f33f309066f49a137e92f76e4259e0237 100644 (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;
   };