diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 0e926adc312..972e4ae8c28 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -4172,22 +4172,34 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { case ISD::SADDO: case ISD::UADDO: { - SDValue LHS = LegalizeOp(Node->getOperand(0)); - SDValue RHS = LegalizeOp(Node->getOperand(1)); + MVT VT = Node->getValueType(0); + switch (TLI.getOperationAction(Node->getOpcode(), VT)) { + default: assert(0 && "This action not supported for this op yet!"); + case TargetLowering::Custom: + Result = TLI.LowerOperation(Op, DAG); + if (Result.getNode()) break; + // FALLTHROUGH + case TargetLowering::Legal: { + SDValue LHS = LegalizeOp(Node->getOperand(0)); + SDValue RHS = LegalizeOp(Node->getOperand(1)); - SDValue Sum = DAG.getNode(ISD::ADD, LHS.getValueType(), LHS, RHS); - MVT OType = SDValue(Node, 1).getValueType(); - SDValue Cmp = DAG.getSetCC(OType, Sum, LHS, - (Node->getOpcode() == ISD::SADDO) ? - ISD::SETLT : ISD::SETULT); + SDValue Sum = DAG.getNode(ISD::ADD, LHS.getValueType(), LHS, RHS); + MVT OType = Node->getValueType(1); + SDValue Cmp = DAG.getSetCC(OType, Sum, LHS, + (Node->getOpcode() == ISD::SADDO) ? + ISD::SETLT : ISD::SETULT); - MVT ValueVTs[] = { LHS.getValueType(), OType }; - SDValue Ops[] = { Sum, Cmp }; + MVT ValueVTs[] = { LHS.getValueType(), OType }; + SDValue Ops[] = { Sum, Cmp }; + + Result = DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2); + SDNode *RNode = Result.getNode(); + DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 0), SDValue(RNode, 0)); + DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 1), SDValue(RNode, 1)); + break; + } + } - Result = DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2); - SDNode *RNode = Result.getNode(); - DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 0), SDValue(RNode, 0)); - DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 1), SDValue(RNode, 1)); break; } } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index f3948f9ee8a..41d4425cc5b 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -4096,9 +4096,8 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { case Intrinsic::sadd_with_overflow: { SDValue Op1 = getValue(I.getOperand(1)); SDValue Op2 = getValue(I.getOperand(2)); - MVT Ty = Op1.getValueType(); - MVT ValueVTs[] = { Ty, MVT::i1 }; + MVT ValueVTs[] = { Op1.getValueType(), MVT::i1 }; SDValue Ops[] = { Op1, Op2 }; SDValue Result = diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 9c5458d54ac..efe7bac72eb 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -780,6 +780,12 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM) // We want to custom lower some of our intrinsics. setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); + // Add with overflow operations are custom lowered. + setOperationAction(ISD::SADDO, MVT::i32, Custom); + setOperationAction(ISD::SADDO, MVT::i64, Custom); + setOperationAction(ISD::UADDO, MVT::i32, Custom); + setOperationAction(ISD::UADDO, MVT::i64, Custom); + // We have target-specific dag combine patterns for the following nodes: setTargetDAGCombine(ISD::VECTOR_SHUFFLE); setTargetDAGCombine(ISD::BUILD_VECTOR); @@ -6142,6 +6148,11 @@ SDValue X86TargetLowering::LowerCTTZ(SDValue Op, SelectionDAG &DAG) { return Op; } +SDValue X86TargetLowering::LowerXADDO(SDValue Op, SelectionDAG &DAG, + ISD::NodeType NTy) { + return SDValue(); +} + SDValue X86TargetLowering::LowerCMP_SWAP(SDValue Op, SelectionDAG &DAG) { MVT T = Op.getValueType(); unsigned Reg = 0; @@ -6321,6 +6332,8 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { 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); // FIXME: REMOVE THIS WHEN LegalizeDAGTypes lands. case ISD::READCYCLECOUNTER: diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index 2358889fda8..e9d8e55e106 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -592,6 +592,8 @@ namespace llvm { 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 LowerCMP_SWAP(SDValue Op, SelectionDAG &DAG); SDValue LowerLOAD_SUB(SDValue Op, SelectionDAG &DAG); SDValue LowerATOMIC_BINARY_64(SDValue Op, SelectionDAG &DAG,