[llvm-commits] [llvm] r60388 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h test/CodeGen/X86/add-with-overflow.ll

Bill Wendling isanbard at gmail.com
Mon Dec 1 17:06:39 PST 2008


Author: void
Date: Mon Dec  1 19:06:39 2008
New Revision: 60388

URL: http://llvm.org/viewvc/llvm-project?rev=60388&view=rev
Log:
Second stab at target-dependent lowering of everyone's favorite nodes: [SU]ADDO

- LowerXADDO lowers [SU]ADDO into an ADD with an implicit EFLAGS define. The
  EFLAGS are fed into a SETCC node which has the conditional COND_O or COND_C,
  depending on the type of ADDO requested.

- LowerBRCOND now recognizes if it's coming from a SETCC node with COND_O or
  COND_C set.

Modified:
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
    llvm/trunk/lib/Target/X86/X86ISelLowering.h
    llvm/trunk/test/CodeGen/X86/add-with-overflow.ll

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=60388&r1=60387&r2=60388&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Dec  1 19:06:39 2008
@@ -5186,6 +5186,8 @@
 
   if (Cond.getOpcode() == ISD::SETCC)
     Cond = LowerSETCC(Cond, DAG);
+  else if (Cond.getOpcode() == ISD::SADDO || Cond.getOpcode() == ISD::UADDO)
+    Cond = LowerXADDO(Cond, DAG);
 
   // If condition flag is set by a X86ISD::CMP, then use it as the condition
   // setting operand in place of the X86ISD::SETCC.
@@ -5199,6 +5201,17 @@
         Opc == X86ISD::UCOMI) {
       Cond = Cmp;
       addTest = false;
+    } else {
+      if (ConstantSDNode *CSDN = dyn_cast<ConstantSDNode>(CC.getNode())) {
+        switch (CSDN->getZExtValue()) {
+        default: break;
+        case X86::COND_O:
+        case X86::COND_C:
+          Cond = Cond.getNode()->getOperand(1);
+          addTest = false;
+          break;
+        }
+      }
     }
   // Also, recognize the pattern generated by an FCMP_UNE. We can emit
   // two branches instead of an explicit OR instruction with a
@@ -6102,31 +6115,27 @@
   return Op;
 }
 
-SDValue X86TargetLowering::LowerXADDO(SDValue Op, SelectionDAG &DAG,
-                                      ISD::NodeType NTy) {
-#if 0
-  // FIXME: Lowering XADDO should use BRCOND as well.
+SDValue X86TargetLowering::LowerXADDO(SDValue Op, SelectionDAG &DAG) {
+  // Lower the "add with overflow" instruction into a regular "add" plus a
+  // "setcc" instruction that checks the overflow flag. The "brcond" lowering
+  // looks for this combo and may remove the "setcc" instruction if the "setcc"
+  // has only one use.
   SDNode *N = Op.getNode();
+  SDValue LHS = N->getOperand(0);
+  SDValue RHS = N->getOperand(1);
 
-  for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
-    SDNode *UseNode = *I;
+  // Also sets EFLAGS.
+  SDVTList VTs = DAG.getVTList(N->getValueType(0), MVT::i32);
+  SDValue Sum = DAG.getNode(ISD::ADD, VTs, LHS, RHS);
+
+  SDValue SetCC =
+    DAG.getNode(X86ISD::SETCC, N->getValueType(1),
+                DAG.getConstant((Op.getOpcode() == ISD::SADDO) ?
+                                  X86::COND_O : X86::COND_C,
+                                MVT::i32), SDValue(Sum.getNode(), 1));
 
-    if (UseNode->getOpcode() == ISD::BRCOND) {
-      // Lower a branch on the overflow/carry flag into a "JO"/"JC"
-      // instruction. Convert the addition into an actual addition, not just a
-      // pseudo node.
-      SDValue LHS = N->getOperand(0);
-      SDValue RHS = N->getOperand(1);
-      SDValue Sum = DAG.getNode(ISD::ADD, LHS.getValueType(), LHS, RHS);
-
-      SDValue Ops[] = { UseNode->getOperand(2), UseNode->getOperand(0) };
-      DAG.SelectNodeTo(UseNode, (NTy == ISD::SADDO) ? X86::JO : X86::JC,
-                       MVT::Other, Ops, 2);
-      return Sum;
-    }
-  }
-#endif
-  return SDValue();
+  DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), SetCC);
+  return Sum;
 }
 
 SDValue X86TargetLowering::LowerCMP_SWAP(SDValue Op, SelectionDAG &DAG) {
@@ -6143,7 +6152,7 @@
     assert(Subtarget->is64Bit() && "Node not type legal!");
     Reg = X86::RAX; size = 8;
     break;
-  };
+  }
   SDValue cpIn = DAG.getCopyToReg(Op.getOperand(0), Reg,
                                     Op.getOperand(2), SDValue());
   SDValue Ops[] = { cpIn.getValue(0),
@@ -6247,8 +6256,8 @@
   case ISD::FLT_ROUNDS_:        return LowerFLT_ROUNDS_(Op, DAG);
   case ISD::CTLZ:               return LowerCTLZ(Op, DAG);
   case ISD::CTTZ:               return LowerCTTZ(Op, DAG);
-  case ISD::SADDO:              return LowerXADDO(Op, DAG, ISD::SADDO);
-  case ISD::UADDO:              return LowerXADDO(Op, DAG, ISD::UADDO);
+  case ISD::SADDO:              return LowerXADDO(Op, DAG);
+  case ISD::UADDO:              return LowerXADDO(Op, DAG);
   case ISD::READCYCLECOUNTER:   return LowerREADCYCLECOUNTER(Op, DAG);
   }
 }

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=60388&r1=60387&r2=60388&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Mon Dec  1 19:06:39 2008
@@ -593,7 +593,7 @@
     SDValue LowerFLT_ROUNDS_(SDValue Op, SelectionDAG &DAG);
     SDValue LowerCTLZ(SDValue Op, SelectionDAG &DAG);
     SDValue LowerCTTZ(SDValue Op, SelectionDAG &DAG);
-    SDValue LowerXADDO(SDValue Op, SelectionDAG &DAG, ISD::NodeType NTy);
+    SDValue LowerXADDO(SDValue Op, SelectionDAG &DAG);
 
     SDValue LowerCMP_SWAP(SDValue Op, SelectionDAG &DAG);
     SDValue LowerLOAD_SUB(SDValue Op, SelectionDAG &DAG);

Modified: llvm/trunk/test/CodeGen/X86/add-with-overflow.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/add-with-overflow.ll?rev=60388&r1=60387&r2=60388&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/X86/add-with-overflow.ll (original)
+++ llvm/trunk/test/CodeGen/X86/add-with-overflow.ll Mon Dec  1 19:06:39 2008
@@ -1,6 +1,5 @@
 ; RUN: llvm-as < %s | llc -march=x86 | grep {jo} | count 1
 ; RUN: llvm-as < %s | llc -march=x86 | grep {jc} | count 1
-; XFAIL: *
 
 @ok = internal constant [4 x i8] c"%d\0A\00"
 @no = internal constant [4 x i8] c"no\0A\00"





More information about the llvm-commits mailing list