[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