[llvm-commits] [llvm] r72707 - in /llvm/trunk: include/llvm/CodeGen/ include/llvm/Target/ lib/CodeGen/SelectionDAG/ lib/Target/X86/ utils/TableGen/

Dale Johannesen dalej at apple.com
Tue Jun 2 11:20:16 PDT 2009


On Jun 2, 2009, at 11:18 AMPDT, Nicolas Geoffray wrote:

> For what it's worth, I'm having failures in VMKit's testsuite with  
> this
> patch. I know you guys won't run VMKit's testsuite :), but if you  
> intend
> to apply the patch, could you run llvm testsuite with it before  
> applying it?
>
> Thanks!
> Nicolas

I've already backed it out, it was causing some bootstrap problem also  
(which I've so far been unable to reproduce:( )

> Evan Cheng wrote:
>> Hi Dale,
>>
>> On first glance, the patch mostly looks good. But I don't care for
>> "supportsHasI1". I would have added ADDC_FLAG / ADDE_FLAG opcodes and
>> have those use MVT::EFLAGS and change ADDC / ADDE to use MVT::i1 to
>> represent the flag value.
>>
>> Thanks,
>>
>> Evan
>>
>> On Jun 1, 2009, at 4:27 PM, Dale Johannesen wrote:
>>
>>
>>> Author: johannes
>>> Date: Mon Jun  1 18:27:20 2009
>>> New Revision: 72707
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=72707&view=rev
>>> Log:
>>> Make the implicit inputs and outputs of target-independent
>>> ADDC/ADDE use MVT::i1 (later, whatever it gets legalized to)
>>> instead of MVT::Flag.  Remove CARRY_FALSE in favor of 0; adjust
>>> all target-independent code to use this format.
>>>
>>> Most targets will still produce a Flag-setting target-dependent
>>> version when selection is done.  X86 is converted to use i32
>>> instead, which means TableGen needs to produce different code
>>> in xxxGenDAGISel.inc.  This keys off the new supportsHasI1 bit
>>> in xxxInstrInfo, currently set only for X86; in principle this
>>> is temporary and should go away when all other targets have
>>> been converted.  All relevant X86 instruction patterns are
>>> modified to represent setting and using EFLAGS explicitly.  The
>>> same can be done on other targets.
>>>
>>> The immediate behavior change is that an ADC/ADD pair are no
>>> longer tightly coupled in the X86 scheduler; they can be
>>> separated by instructions that don't clobber the flags (MOV).
>>> I will soon add some peephole optimizations based on using
>>> other instructions that set the flags to feed into ADC.
>>>
>>>
>>> Modified:
>>>   llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
>>>   llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
>>>   llvm/trunk/include/llvm/Target/Target.td
>>>   llvm/trunk/include/llvm/Target/TargetSelectionDAG.td
>>>   llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
>>>   llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
>>>   llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
>>>   llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
>>>   llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
>>>   llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
>>>   llvm/trunk/lib/Target/X86/X86ISelLowering.h
>>>   llvm/trunk/lib/Target/X86/X86Instr64bit.td
>>>   llvm/trunk/lib/Target/X86/X86InstrInfo.td
>>>   llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp
>>>   llvm/trunk/utils/TableGen/CodeGenTarget.cpp
>>>   llvm/trunk/utils/TableGen/CodeGenTarget.h
>>>   llvm/trunk/utils/TableGen/DAGISelEmitter.cpp
>>>
>>> Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=72707&r1=72706&r2=72707&view=diff
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> = 
>>> = 
>>> ====================================================================
>>> --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original)
>>> +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Mon Jun  1
>>> 18:27:20 2009
>>> @@ -324,6 +324,14 @@
>>>    return getNode(ISD::CopyToReg, dl, MVT::Other, Chain,
>>>                   getRegister(Reg, N.getValueType()), N);
>>>  }
>>> +  // This version of getCopyToReg has the register (and its type)
>>> as an
>>> +  // explicit output.
>>> +  SDValue getCopyToReg(SDValue Chain, DebugLoc dl, MVT VT, unsigned
>>> Reg,
>>> +                       SDValue N) {
>>> +    SDVTList VTs = getVTList(MVT::Other, VT);
>>> +    SDValue Ops[] = { Chain, getRegister(Reg, VT), N};
>>> +    return getNode(ISD::CopyToReg, dl, VTs, Ops, 3);
>>> +  }
>>>
>>>  // This version of the getCopyToReg method takes an extra operand,
>>> which
>>>  // indicates that there is potentially an incoming flag value (if
>>> Flag is not
>>>
>>> Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=72707&r1=72706&r2=72707&view=diff
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> = 
>>> = 
>>> ====================================================================
>>> --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original)
>>> +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Mon Jun  1
>>> 18:27:20 2009
>>> @@ -242,14 +242,11 @@
>>>    // remainder result.
>>>    SDIVREM, UDIVREM,
>>>
>>> -    // CARRY_FALSE - This node is used when folding other nodes,
>>> -    // like ADDC/SUBC, which indicate the carry result is always
>>> false.
>>> -    CARRY_FALSE,
>>> -
>>>    // Carry-setting nodes for multiple precision addition and
>>> subtraction.
>>>    // These nodes take two operands of the same value type, and
>>> produce two
>>>    // results.  The first result is the normal add or sub result,
>>> the second
>>> -    // result is the carry flag result.
>>> +    // result is the carry flag result (type i1 or whatever it got
>>> expanded to
>>> +    // for the target, value 0 or 1).
>>>    ADDC, SUBC,
>>>
>>>    // Carry-using nodes for multiple precision addition and
>>> subtraction.  These
>>> @@ -258,7 +255,8 @@
>>>    // produce two results; the normal result of the add or sub, and
>>> the output
>>>    // carry flag.  These nodes both read and write a carry flag to
>>> allow them
>>>    // to them to be chained together for add and sub of arbitrarily
>>> large
>>> -    // values.
>>> +    // values.  The carry flag (input and output) has type i1 or
>>> whatever it
>>> +    // got expanded to for the target, and has value 0 or 1.
>>>    ADDE, SUBE,
>>>
>>>    // RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for
>>> addition.
>>>
>>> Modified: llvm/trunk/include/llvm/Target/Target.td
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=72707&r1=72706&r2=72707&view=diff
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> = 
>>> = 
>>> ====================================================================
>>> --- llvm/trunk/include/llvm/Target/Target.td (original)
>>> +++ llvm/trunk/include/llvm/Target/Target.td Mon Jun  1 18:27:20  
>>> 2009
>>> @@ -326,6 +326,11 @@
>>>  // Sparc manual specifies its instructions in the format [31..0]
>>> (big), while
>>>  // PowerPC specifies them using the format [0..31] (little).
>>>  bit isLittleEndianEncoding = 0;
>>> +
>>> +  // Targets that can support the HasI1 argument on ADDC and ADDE,
>>> rather than
>>> +  // Flag, have this bit set.  This is transitional and should go
>>> away when all
>>> +  // targets have been switched over.
>>> +  bit supportsHasI1 = 0;
>>> }
>>>
>>> // Standard Instructions.
>>>
>>> Modified: llvm/trunk/include/llvm/Target/TargetSelectionDAG.td
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSelectionDAG.td?rev=72707&r1=72706&r2=72707&view=diff
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> = 
>>> = 
>>> ====================================================================
>>> --- llvm/trunk/include/llvm/Target/TargetSelectionDAG.td (original)
>>> +++ llvm/trunk/include/llvm/Target/TargetSelectionDAG.td Mon Jun  1
>>> 18:27:20 2009
>>> @@ -216,6 +216,8 @@
>>> def SDNPMayLoad     : SDNodeProperty;   // May read memory, sets
>>> 'mayLoad'.
>>> def SDNPSideEffect  : SDNodeProperty;   // Sets
>>> 'HasUnmodelledSideEffects'.
>>> def SDNPMemOperand  : SDNodeProperty;   // Touches memory, has assoc
>>> MemOperand
>>> +def SDNPInI1        : SDNodeProperty;   // Read an extra I1 operand
>>> +def SDNPOutI1       : SDNodeProperty;   // Write an extra I1 result
>>>
>>> //
>>> =
>>> =
>>> =
>>> ----------------------------------------------------------------------=
>>> ==//
>>> // Selection DAG Node definitions.
>>> @@ -289,13 +291,13 @@
>>> def xor        : SDNode<"ISD::XOR"       , SDTIntBinOp,
>>>                        [SDNPCommutative, SDNPAssociative]>;
>>> def addc       : SDNode<"ISD::ADDC"      , SDTIntBinOp,
>>> -                        [SDNPCommutative, SDNPOutFlag]>;
>>> +                        [SDNPCommutative, SDNPOutI1]>;
>>> def adde       : SDNode<"ISD::ADDE"      , SDTIntBinOp,
>>> -                        [SDNPCommutative, SDNPOutFlag,  
>>> SDNPInFlag]>;
>>> +                        [SDNPCommutative, SDNPInI1, SDNPOutI1]>;
>>> def subc       : SDNode<"ISD::SUBC"      , SDTIntBinOp,
>>> -                        [SDNPOutFlag]>;
>>> +                        [SDNPOutI1]>;
>>> def sube       : SDNode<"ISD::SUBE"      , SDTIntBinOp,
>>> -                        [SDNPOutFlag, SDNPInFlag]>;
>>> +                        [SDNPInI1, SDNPOutI1]>;
>>>
>>> def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>;
>>> def bswap      : SDNode<"ISD::BSWAP"      , SDTIntUnaryOp>;
>>>
>>> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=72707&r1=72706&r2=72707&view=diff
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> = 
>>> = 
>>> ====================================================================
>>> --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
>>> +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Jun  1
>>> 18:27:20 2009
>>> @@ -1085,8 +1085,7 @@
>>>  // If the flag result is dead, turn this into an ADD.
>>>  if (N->hasNUsesOfValue(0, 1))
>>>    return CombineTo(N, DAG.getNode(ISD::ADD, N->getDebugLoc(), VT,
>>> N1, N0),
>>> -                     DAG.getNode(ISD::CARRY_FALSE,
>>> -                                 N->getDebugLoc(), MVT::Flag));
>>> +                     DAG.getConstant(0, N->getValueType(1)));
>>>
>>>  // canonicalize constant to RHS.
>>>  if (N0C && !N1C)
>>> @@ -1094,10 +1093,9 @@
>>>
>>>  // fold (addc x, 0) -> x + no carry out
>>>  if (N1C && N1C->isNullValue())
>>> -    return CombineTo(N, N0, DAG.getNode(ISD::CARRY_FALSE,
>>> -                                        N->getDebugLoc(),
>>> MVT::Flag));
>>> +    return CombineTo(N, N0, DAG.getConstant(0, N1.getValueType()));
>>>
>>> -  // fold (addc a, b) -> (or a, b), CARRY_FALSE iff a and b share
>>> no bits.
>>> +  // fold (addc a, b) -> (or a, b), 0 iff a and b share no bits.
>>>  APInt LHSZero, LHSOne;
>>>  APInt RHSZero, RHSOne;
>>>  APInt Mask = APInt::getAllOnesValue(VT.getSizeInBits());
>>> @@ -1111,8 +1109,7 @@
>>>    if ((RHSZero & (~LHSZero & Mask)) == (~LHSZero & Mask) ||
>>>        (LHSZero & (~RHSZero & Mask)) == (~RHSZero & Mask))
>>>      return CombineTo(N, DAG.getNode(ISD::OR, N->getDebugLoc(), VT,
>>> N0, N1),
>>> -                       DAG.getNode(ISD::CARRY_FALSE,
>>> -                                   N->getDebugLoc(), MVT::Flag));
>>> +                       DAG.getConstant(0, N1.getValueType()));
>>>  }
>>>
>>>  return SDValue();
>>> @@ -1131,8 +1128,9 @@
>>>                       N1, N0, CarryIn);
>>>
>>>  // fold (adde x, y, false) -> (addc x, y)
>>> -  if (CarryIn.getOpcode() == ISD::CARRY_FALSE)
>>> -    return DAG.getNode(ISD::ADDC, N->getDebugLoc(), N->getVTList(),
>>> N1, N0);
>>> +  if (ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(CarryIn))
>>> +    if (N2C->getAPIntValue()==0)
>>> +      return DAG.getNode(ISD::ADDC, N->getDebugLoc(), N->getVTList
>>> (), N1, N0);
>>>
>>>  return SDValue();
>>> }
>>>
>>> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ 
>>> LegalizeIntegerTypes.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp?rev=72707&r1=72706&r2=72707&view=diff
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> = 
>>> = 
>>> ====================================================================
>>> --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
>>> (original)
>>> +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Mon
>>> Jun  1 18:27:20 2009
>>> @@ -98,6 +98,10 @@
>>>  case ISD::USUBO:       Res = PromoteIntRes_UADDSUBO(N, ResNo);
>>> break;
>>>  case ISD::SMULO:
>>>  case ISD::UMULO:       Res = PromoteIntRes_XMULO(N, ResNo); break;
>>> +  case ISD::ADDC:
>>> +  case ISD::SUBC:        Res = PromoteIntRes_ADDSUBC(N, ResNo);
>>> break;
>>> +  case ISD::ADDE:
>>> +  case ISD::SUBE:        Res = PromoteIntRes_ADDSUBE(N, ResNo);
>>> break;
>>>
>>>  case ISD::ATOMIC_LOAD_ADD:
>>>  case ISD::ATOMIC_LOAD_SUB:
>>> @@ -121,6 +125,35 @@
>>>    SetPromotedInteger(SDValue(N, ResNo), Res);
>>> }
>>>
>>> +SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBC(SDNode *N, unsigned
>>> ResNo) {
>>> +  // Only the carry bit result is expected to be promoted.
>>> +  assert(ResNo == 1 && "Only carry bit result promotion currently
>>> supported!");
>>> +  return PromoteIntRes_Overflow(N);
>>> +}
>>> +
>>> +SDValue DAGTypeLegalizer::PromoteIntRes_ADDSUBE(SDNode *N, unsigned
>>> ResNo) {
>>> +  // Only the carry bit result is expected to be promoted.
>>> +  assert(ResNo == 1 && "Only carry bit result promotion currently
>>> supported!");
>>> +  // This is a ternary operator, so clone a slightly modified
>>> +  // PromoteIntRes_Overflow here (this is the only client).
>>> +  if (ResNo == 1) {
>>> +    // Simply change the return type of the boolean result.
>>> +    MVT NVT = TLI.getTypeToTransformTo(N->getValueType(1));
>>> +    MVT ValueVTs[] = { N->getValueType(0), NVT };
>>> +    SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N-
>>>
>>>> getOperand(2) };
>>>>
>>> +    SDValue Res = DAG.getNode(N->getOpcode(), N->getDebugLoc(),
>>> +                              DAG.getVTList(ValueVTs, 2), Ops, 3);
>>> +
>>> +    // Modified the sum result - switch anything that used the old
>>> sum to use
>>> +    // the new one.
>>> +    ReplaceValueWith(SDValue(N, 0), Res);
>>> +
>>> +    return SDValue(Res.getNode(), 1);
>>> +  }
>>> +  assert(0 && "Do not know how to promote this operator!");
>>> +  abort();
>>> +}
>>> +
>>> SDValue DAGTypeLegalizer::PromoteIntRes_AssertSext(SDNode *N) {
>>>  // Sign-extend the new bits, and continue the assertion.
>>>  SDValue Op = SExtPromotedInteger(N->getOperand(0));
>>> @@ -419,7 +452,7 @@
>>>  return Res;
>>> }
>>>
>>> -/// Promote the overflow flag of an overflowing arithmetic node.
>>> +/// Promote the overflow or carry result of an overflowing
>>> arithmetic node.
>>> SDValue DAGTypeLegalizer::PromoteIntRes_Overflow(SDNode *N) {
>>>  // Simply change the return type of the boolean result.
>>>  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(1));
>>> @@ -666,6 +699,8 @@
>>>    assert(0 && "Do not know how to promote this operator's
>>> operand!");
>>>    abort();
>>>
>>> +  case ISD::ADDE:
>>> +  case ISD::SUBE:         Res = PromoteIntOp_ADDSUBE(N, OpNo);  
>>> break;
>>>  case ISD::ANY_EXTEND:   Res = PromoteIntOp_ANY_EXTEND(N); break;
>>>  case ISD::BIT_CONVERT:  Res = PromoteIntOp_BIT_CONVERT(N); break;
>>>  case ISD::BR_CC:        Res = PromoteIntOp_BR_CC(N, OpNo); break;
>>> @@ -743,6 +778,13 @@
>>>  }
>>> }
>>>
>>> +SDValue DAGTypeLegalizer::PromoteIntOp_ADDSUBE(SDNode *N, unsigned
>>> OpNo) {
>>> +  assert(OpNo == 2 && "Don't know how to promote this operand!");
>>> +  return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0),
>>> +                                N->getOperand(1),
>>> +                                GetPromotedInteger(N->getOperand
>>> (2)));
>>> +}
>>> +
>>> SDValue DAGTypeLegalizer::PromoteIntOp_ANY_EXTEND(SDNode *N) {
>>>  SDValue Op = GetPromotedInteger(N->getOperand(0));
>>>  return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), N-
>>>
>>>> getValueType(0), Op);
>>>>
>>> @@ -1063,7 +1105,7 @@
>>>               TLI.isOperationLegalOrCustom(ISD::ADDC,
>>>                                            TLI.getTypeToExpandTo
>>> (NVT))) {
>>>      // Emit this X << 1 as X+X.
>>> -      SDVTList VTList = DAG.getVTList(NVT, MVT::Flag);
>>> +      SDVTList VTList = DAG.getVTList(NVT, MVT::i1);
>>>      SDValue LoOps[2] = { InL, InL };
>>>      Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2);
>>>      SDValue HiOps[3] = { InH, InH, Lo.getValue(1) };
>>> @@ -1299,7 +1341,7 @@
>>>                                 TLI.getTypeToExpandTo(NVT));
>>>
>>>  if (hasCarry) {
>>> -    SDVTList VTList = DAG.getVTList(NVT, MVT::Flag);
>>> +    SDVTList VTList = DAG.getVTList(NVT, MVT::i1);
>>>    if (N->getOpcode() == ISD::ADD) {
>>>      Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2);
>>>      HiOps[2] = Lo.getValue(1);
>>> @@ -1344,7 +1386,7 @@
>>>  DebugLoc dl = N->getDebugLoc();
>>>  GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
>>>  GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
>>> -  SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
>>> +  SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::i1);
>>>  SDValue LoOps[2] = { LHSL, RHSL };
>>>  SDValue HiOps[3] = { LHSH, RHSH };
>>>
>>> @@ -1358,8 +1400,8 @@
>>>    Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3);
>>>  }
>>>
>>> -  // Legalized the flag result - switch anything that used the old
>>> flag to
>>> -  // use the new one.
>>> +  // Legalized the second result (carry bit) - switch anything that
>>> used the
>>> +  // result to use the new one.
>>>  ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
>>> }
>>>
>>> @@ -1370,7 +1412,7 @@
>>>  DebugLoc dl = N->getDebugLoc();
>>>  GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
>>>  GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
>>> -  SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
>>> +  SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::i1);
>>>  SDValue LoOps[3] = { LHSL, RHSL, N->getOperand(2) };
>>>  SDValue HiOps[3] = { LHSH, RHSH };
>>>
>>> @@ -1378,8 +1420,8 @@
>>>  HiOps[2] = Lo.getValue(1);
>>>  Hi = DAG.getNode(N->getOpcode(), dl, VTList, HiOps, 3);
>>>
>>> -  // Legalized the flag result - switch anything that used the old
>>> flag to
>>> -  // use the new one.
>>> +  // Legalized the second result (carry bit) - switch anything that
>>> used the
>>> +  // result to use the new one.
>>>  ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
>>> }
>>>
>>>
>>> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=72707&r1=72706&r2=72707&view=diff
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> = 
>>> = 
>>> ====================================================================
>>> --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original)
>>> +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Mon Jun  1
>>> 18:27:20 2009
>>> @@ -242,6 +242,8 @@
>>>
>>>  // Integer Result Promotion.
>>>  void PromoteIntegerResult(SDNode *N, unsigned ResNo);
>>> +  SDValue PromoteIntRes_ADDSUBC(SDNode *N, unsigned ResNo);
>>> +  SDValue PromoteIntRes_ADDSUBE(SDNode *N, unsigned ResNo);
>>>  SDValue PromoteIntRes_AssertSext(SDNode *N);
>>>  SDValue PromoteIntRes_AssertZext(SDNode *N);
>>>  SDValue PromoteIntRes_Atomic1(AtomicSDNode *N);
>>> @@ -278,6 +280,7 @@
>>>
>>>  // Integer Operand Promotion.
>>>  bool PromoteIntegerOperand(SDNode *N, unsigned OperandNo);
>>> +  SDValue PromoteIntOp_ADDSUBE(SDNode *N, unsigned OpNo);
>>>  SDValue PromoteIntOp_ANY_EXTEND(SDNode *N);
>>>  SDValue PromoteIntOp_BIT_CONVERT(SDNode *N);
>>>  SDValue PromoteIntOp_BUILD_PAIR(SDNode *N);
>>>
>>> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp?rev=72707&r1=72706&r2=72707&view=diff
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> = 
>>> = 
>>> ====================================================================
>>> --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
>>> (original)
>>> +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp Mon
>>> Jun  1 18:27:20 2009
>>> @@ -268,6 +268,13 @@
>>>  unsigned N = Node->getNumOperands();
>>>  while (N && Node->getOperand(N - 1).getValueType() == MVT::Flag)
>>>    --N;
>>> +  // Skip hard registers set as a side effect (i.e. not result 0).
>>> +  while (N && Node->getOperand(N - 1).getOpcode() == ISD::CopyToReg
>>> &&
>>> +         Node->getOperand(N-1).getResNo() != 0 &&
>>> +         !TargetRegisterInfo::isVirtualRegister(
>>> +                dyn_cast<RegisterSDNode>(Node->getOperand
>>> (N-1).getOperand(1))
>>> +                ->getReg()))
>>> +    --N;
>>>  if (N && Node->getOperand(N - 1).getValueType() == MVT::Other)
>>>    --N; // Ignore chain if it exists.
>>>  return N;
>>>
>>> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=72707&r1=72706&r2=72707&view=diff
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> = 
>>> = 
>>> ====================================================================
>>> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
>>> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon Jun  1
>>> 18:27:20 2009
>>> @@ -5257,7 +5257,6 @@
>>>  case ISD::EXTRACT_SUBVECTOR:   return "extract_subvector";
>>>  case ISD::SCALAR_TO_VECTOR:    return "scalar_to_vector";
>>>  case ISD::VECTOR_SHUFFLE:      return "vector_shuffle";
>>> -  case ISD::CARRY_FALSE:         return "carry_false";
>>>  case ISD::ADDC:        return "addc";
>>>  case ISD::ADDE:        return "adde";
>>>  case ISD::SADDO:       return "saddo";
>>>
>>> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=72707&r1=72706&r2=72707&view=diff
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> = 
>>> = 
>>> ====================================================================
>>> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
>>> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Jun  1
>>> 18:27:20 2009
>>> @@ -190,6 +190,28 @@
>>>    setOperationAction(ISD::BIT_CONVERT      , MVT::i32  , Expand);
>>>  }
>>>
>>> +  // ADDE and SUBE are lowered to local versions that contain
>>> EFLAGS explicitly.
>>> +  // ADDC and SUBC are lowered to local versions so EFLAGS will be
>>> an i32
>>> +  // rather than the Flag used by the generic patterns.
>>> +  setOperationAction(ISD::ADDC            , MVT::i8     , Custom);
>>> +  setOperationAction(ISD::ADDC            , MVT::i16    , Custom);
>>> +  setOperationAction(ISD::ADDC            , MVT::i32    , Custom);
>>> +  setOperationAction(ISD::SUBC            , MVT::i8     , Custom);
>>> +  setOperationAction(ISD::SUBC            , MVT::i16    , Custom);
>>> +  setOperationAction(ISD::SUBC            , MVT::i32    , Custom);
>>> +  setOperationAction(ISD::ADDE            , MVT::i8     , Custom);
>>> +  setOperationAction(ISD::ADDE            , MVT::i16    , Custom);
>>> +  setOperationAction(ISD::ADDE            , MVT::i32    , Custom);
>>> +  setOperationAction(ISD::SUBE            , MVT::i8     , Custom);
>>> +  setOperationAction(ISD::SUBE            , MVT::i16    , Custom);
>>> +  setOperationAction(ISD::SUBE            , MVT::i32    , Custom);
>>> +  if (Subtarget->is64Bit()) {
>>> +    setOperationAction(ISD::ADDC            , MVT::i64    ,  
>>> Custom);
>>> +    setOperationAction(ISD::SUBC            , MVT::i64    ,  
>>> Custom);
>>> +    setOperationAction(ISD::ADDE            , MVT::i64    ,  
>>> Custom);
>>> +    setOperationAction(ISD::SUBE            , MVT::i64    ,  
>>> Custom);
>>> +  }
>>> +
>>>  // Scalar integer divide and remainder are lowered to use
>>> operations that
>>>  // produce two results, to match the available instructions. This
>>> exposes
>>>  // the two-result form to trivial CSE, which is able to combine x/
>>> y and x%y
>>> @@ -6475,6 +6497,21 @@
>>>  return Sum;
>>> }
>>>
>>> +SDValue X86TargetLowering::LowerADDSUBE(SDValue Op, SelectionDAG
>>> &DAG) {
>>> +  DebugLoc dl = Op.getDebugLoc();
>>> +  SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::i32);
>>> +  return DAG.getNode(Op.getOpcode()==ISD::ADDE ? X86ISD::ADDE :
>>> X86ISD::SUBE,
>>> +                     dl, VTs, Op.getOperand(0), Op.getOperand(1),
>>> +                     Op.getOperand(2).getValue(1));
>>> +}
>>> +
>>> +SDValue X86TargetLowering::LowerADDSUBC(SDValue Op, SelectionDAG
>>> &DAG) {
>>> +  DebugLoc dl = Op.getDebugLoc();
>>> +  SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::i32);
>>> +  return DAG.getNode(Op.getOpcode()==ISD::ADDC ? X86ISD::ADD :
>>> X86ISD::SUB,
>>> +                     dl, VTs, Op.getOperand(0), Op.getOperand(1));
>>> +}
>>> +
>>> SDValue X86TargetLowering::LowerCMP_SWAP(SDValue Op, SelectionDAG
>>> &DAG) {
>>>  MVT T = Op.getValueType();
>>>  DebugLoc dl = Op.getDebugLoc();
>>> @@ -6543,6 +6580,10 @@
>>> SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG
>>> &DAG) {
>>>  switch (Op.getOpcode()) {
>>>  default: assert(0 && "Should not custom lower this!");
>>> +  case ISD::ADDC:
>>> +  case ISD::SUBC:               return LowerADDSUBC(Op,DAG);
>>> +  case ISD::ADDE:
>>> +  case ISD::SUBE:               return LowerADDSUBE(Op,DAG);
>>>  case ISD::ATOMIC_CMP_SWAP:    return LowerCMP_SWAP(Op,DAG);
>>>  case ISD::ATOMIC_LOAD_SUB:    return LowerLOAD_SUB(Op,DAG);
>>>  case ISD::BUILD_VECTOR:       return LowerBUILD_VECTOR(Op, DAG);
>>> @@ -6791,6 +6832,10 @@
>>>  case X86ISD::INC:                return "X86ISD::INC";
>>>  case X86ISD::DEC:                return "X86ISD::DEC";
>>>  case X86ISD::MUL_IMM:            return "X86ISD::MUL_IMM";
>>> +  case X86ISD::ADDE:               return "X86ISD::ADDE";
>>> +  case X86ISD::SUBE:               return "X86ISD::SUBE";
>>> +  case X86ISD::ADDC:               return "X86ISD::ADDC";
>>> +  case X86ISD::SUBC:               return "X86ISD::SUBC";
>>>  }
>>> }
>>>
>>>
>>> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=72707&r1=72706&r2=72707&view=diff
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> = 
>>> = 
>>> ====================================================================
>>> --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)
>>> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Mon Jun  1 18:27:20
>>> 2009
>>> @@ -243,6 +243,14 @@
>>>      ADD, SUB, SMUL, UMUL,
>>>      INC, DEC,
>>>
>>> +      // ADDC, SUBC - Arithmetic operations setting carry bit.  The
>>> normal
>>> +      // arithmetic operations do this, but they represent it as
>>> Flag, and
>>> +      // we want the i32 EFLAGS register here.
>>> +      ADDC, SUBC,
>>> +
>>> +      // ADDE, SUBE - Arithmetic operations with extra FLAGS
>>> (EFLAGS) inputs.
>>> +      ADDE, SUBE,
>>> +
>>>      // MUL_IMM - X86 specific multiply by immediate.
>>>      MUL_IMM
>>>    };
>>> @@ -576,7 +584,9 @@
>>>
>>>    std::pair<SDValue,SDValue> FP_TO_INTHelper(SDValue Op,
>>> SelectionDAG &DAG,
>>>                                               bool isSigned);
>>> -
>>> +
>>> +    SDValue LowerADDSUBC(SDValue Op, SelectionDAG &DAG);
>>> +    SDValue LowerADDSUBE(SDValue Op, SelectionDAG &DAG);
>>>    SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG);
>>>    SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG);
>>>    SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG);
>>>
>>> Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=72707&r1=72706&r2=72707&view=diff
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> = 
>>> = 
>>> ====================================================================
>>> --- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original)
>>> +++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Mon Jun  1 18:27:20
>>> 2009
>>> @@ -383,31 +383,52 @@
>>> let Uses = [EFLAGS] in {
>>> let isTwoAddress = 1 in {
>>> let isCommutable = 1 in
>>> -def ADC64rr  : RI<0x11, MRMDestReg, (outs GR64:$dst), (ins
>>> GR64:$src1, GR64:$src2),
>>> +def ADC64rr  : RI<0x11, MRMDestReg, (outs GR64:$dst),
>>> +                                    (ins GR64:$src1, GR64:$src2),
>>>                  "adc{q}\t{$src2, $dst|$dst, $src2}",
>>> -                  [(set GR64:$dst, (adde GR64:$src1,  
>>> GR64:$src2))]>;
>>> +                  [(set GR64:$dst,
>>> +                        (X86adde_flag GR64:$src1, GR64:$src2,
>>> EFLAGS)),
>>> +                   (implicit EFLAGS)]>;
>>>
>>> -def ADC64rm  : RI<0x13, MRMSrcMem , (outs GR64:$dst), (ins
>>> GR64:$src1, i64mem:$src2),
>>> +def ADC64rm  : RI<0x13, MRMSrcMem , (outs GR64:$dst),
>>> +                                    (ins GR64:$src1, i64mem:$src2),
>>>                  "adc{q}\t{$src2, $dst|$dst, $src2}",
>>> -                  [(set GR64:$dst, (adde GR64:$src1, (load addr:
>>> $src2)))]>;
>>> +                  [(set GR64:$dst,
>>> +                        (X86adde_flag GR64:$src1, (load addr:
>>> $src2), EFLAGS)),
>>> +                   (implicit EFLAGS)]>;
>>>
>>> -def ADC64ri8 : RIi8<0x83, MRM2r, (outs GR64:$dst), (ins GR64:$src1,
>>> i64i8imm:$src2),
>>> +def ADC64ri8 : RIi8<0x83, MRM2r, (outs GR64:$dst),
>>> +                                 (ins GR64:$src1, i64i8imm:$src2),
>>>                    "adc{q}\t{$src2, $dst|$dst, $src2}",
>>> -                    [(set GR64:$dst, (adde GR64:$src1,
>>> i64immSExt8:$src2))]>;
>>> -def ADC64ri32 : RIi32<0x81, MRM2r, (outs GR64:$dst), (ins
>>> GR64:$src1, i64i32imm:$src2),
>>> +                    [(set GR64:$dst,
>>> +                          (X86adde_flag GR64:$src1,
>>> i64immSExt8:$src2, EFLAGS)),
>>> +                     (implicit EFLAGS)]>;
>>> +def ADC64ri32 : RIi32<0x81, MRM2r, (outs GR64:$dst),
>>> +                                   (ins GR64:$src1, i64i32imm: 
>>> $src2),
>>>                      "adc{q}\t{$src2, $dst|$dst, $src2}",
>>> -                      [(set GR64:$dst, (adde GR64:$src1,
>>> i64immSExt32:$src2))]>;
>>> +                      [(set GR64:$dst,
>>> +                            (X86adde_flag GR64:$src1,
>>> i64immSExt32:$src2,
>>> +                                          EFLAGS)),
>>> +                       (implicit EFLAGS)]>;
>>> } // isTwoAddress
>>>
>>> def ADC64mr  : RI<0x11, MRMDestMem, (outs), (ins i64mem:$dst,
>>> GR64:$src2),
>>>                  "adc{q}\t{$src2, $dst|$dst, $src2}",
>>> -                  [(store (adde (load addr:$dst), GR64:$src2),  
>>> addr:
>>> $dst)]>;
>>> +                  [(store (X86adde_flag (load addr:$dst),
>>> GR64:$src2, EFLAGS),
>>> +                          addr:$dst),
>>> +                   (implicit EFLAGS)]>;
>>> def ADC64mi8 : RIi8<0x83, MRM2m, (outs), (ins i64mem:$dst,  
>>> i64i8imm :
>>> $src2),
>>>                    "adc{q}\t{$src2, $dst|$dst, $src2}",
>>> -                 [(store (adde (load addr:$dst),
>>> i64immSExt8:$src2), addr:$dst)]>;
>>> +                 [(store (X86adde_flag (load addr:$dst),
>>> i64immSExt8:$src2,
>>> +                                       EFLAGS),
>>> +                         addr:$dst),
>>> +                  (implicit EFLAGS)]>;
>>> def ADC64mi32 : RIi32<0x81, MRM2m, (outs), (ins i64mem:$dst,
>>> i64i32imm:$src2),
>>>                      "adc{q}\t{$src2, $dst|$dst, $src2}",
>>> -                 [(store (adde (load addr:$dst),
>>> i64immSExt8:$src2), addr:$dst)]>;
>>> +                 [(store (X86adde_flag (load addr:$dst),
>>> i64immSExt8:$src2,
>>> +                                       EFLAGS),
>>> +                         addr:$dst),
>>> +                  (implicit EFLAGS)]>;
>>> } // Uses = [EFLAGS]
>>>
>>> let isTwoAddress = 1 in {
>>> @@ -456,31 +477,52 @@
>>>
>>> let Uses = [EFLAGS] in {
>>> let isTwoAddress = 1 in {
>>> -def SBB64rr    : RI<0x19, MRMDestReg, (outs GR64:$dst), (ins
>>> GR64:$src1, GR64:$src2),
>>> +def SBB64rr    : RI<0x19, MRMDestReg, (outs GR64:$dst),
>>> +                                      (ins GR64:$src1, GR64:$src2),
>>>                    "sbb{q}\t{$src2, $dst|$dst, $src2}",
>>> -                    [(set GR64:$dst, (sube GR64:$src1,  
>>> GR64:$src2))]
>>>
>>>> ;
>>>>
>>> +                    [(set GR64:$dst,
>>> +                          (X86sube_flag GR64:$src1, GR64:$src2,
>>> EFLAGS)),
>>> +                     (implicit EFLAGS)]>;
>>>
>>> -def SBB64rm  : RI<0x1B, MRMSrcMem, (outs GR64:$dst), (ins
>>> GR64:$src1, i64mem:$src2),
>>> +def SBB64rm  : RI<0x1B, MRMSrcMem, (outs GR64:$dst),
>>> +                                   (ins GR64:$src1, i64mem:$src2),
>>>                  "sbb{q}\t{$src2, $dst|$dst, $src2}",
>>> -                  [(set GR64:$dst, (sube GR64:$src1, (load addr:
>>> $src2)))]>;
>>> +                  [(set GR64:$dst,
>>> +                        (X86sube_flag GR64:$src1, (load addr:
>>> $src2), EFLAGS)),
>>> +                   (implicit EFLAGS)]>;
>>>
>>> -def SBB64ri8 : RIi8<0x83, MRM3r, (outs GR64:$dst), (ins GR64:$src1,
>>> i64i8imm:$src2),
>>> +def SBB64ri8 : RIi8<0x83, MRM3r, (outs GR64:$dst),
>>> +                                 (ins GR64:$src1, i64i8imm:$src2),
>>>                    "sbb{q}\t{$src2, $dst|$dst, $src2}",
>>> -                    [(set GR64:$dst, (sube GR64:$src1,
>>> i64immSExt8:$src2))]>;
>>> -def SBB64ri32 : RIi32<0x81, MRM3r, (outs GR64:$dst), (ins
>>> GR64:$src1, i64i32imm:$src2),
>>> +                    [(set GR64:$dst,
>>> +                          (X86sube_flag GR64:$src1,
>>> i64immSExt8:$src2, EFLAGS)),
>>> +                     (implicit EFLAGS)]>;
>>> +def SBB64ri32 : RIi32<0x81, MRM3r, (outs GR64:$dst),
>>> +                                   (ins GR64:$src1, i64i32imm: 
>>> $src2),
>>>                      "sbb{q}\t{$src2, $dst|$dst, $src2}",
>>> -                      [(set GR64:$dst, (sube GR64:$src1,
>>> i64immSExt32:$src2))]>;
>>> +                      [(set GR64:$dst,
>>> +                            (X86sube_flag GR64:$src1,
>>> i64immSExt32:$src2,
>>> +                                          EFLAGS)),
>>> +                       (implicit EFLAGS)]>;
>>> } // isTwoAddress
>>>
>>> def SBB64mr  : RI<0x19, MRMDestMem, (outs), (ins i64mem:$dst,
>>> GR64:$src2),
>>>                  "sbb{q}\t{$src2, $dst|$dst, $src2}",
>>> -                  [(store (sube (load addr:$dst), GR64:$src2),  
>>> addr:
>>> $dst)]>;
>>> +                  [(store (X86sube_flag (load addr:$dst),
>>> GR64:$src2, EFLAGS),
>>> +                          addr:$dst),
>>> +                   (implicit EFLAGS)]>;
>>> def SBB64mi8 : RIi8<0x83, MRM3m, (outs), (ins i64mem:$dst,  
>>> i64i8imm :
>>> $src2),
>>>                    "sbb{q}\t{$src2, $dst|$dst, $src2}",
>>> -               [(store (sube (load addr:$dst), i64immSExt8:$src2),
>>> addr:$dst)]>;
>>> +               [(store (X86sube_flag (load addr:$dst),
>>> i64immSExt8:$src2,
>>> +                                     EFLAGS),
>>> +                       addr:$dst),
>>> +                (implicit EFLAGS)]>;
>>> def SBB64mi32 : RIi32<0x81, MRM3m, (outs), (ins i64mem:$dst,
>>> i64i32imm:$src2),
>>>                      "sbb{q}\t{$src2, $dst|$dst, $src2}",
>>> -              [(store (sube (load addr:$dst), i64immSExt32:$src2),
>>> addr:$dst)]>;
>>> +              [(store (X86sube_flag (load addr:$dst),
>>> i64immSExt32:$src2,
>>> +                                    EFLAGS),
>>> +                      addr:$dst),
>>> +               (implicit EFLAGS)]>;
>>> } // Uses = [EFLAGS]
>>> } // Defs = [EFLAGS]
>>>
>>>
>>> Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=72707&r1=72706&r2=72707&view=diff
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> = 
>>> = 
>>> ====================================================================
>>> --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)
>>> +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Mon Jun  1 18:27:20  
>>> 2009
>>> @@ -34,6 +34,11 @@
>>>                                            [SDTCisSameAs<0, 1>,
>>>                                             SDTCisSameAs<0, 2>,
>>>                                             SDTCisInt<0>]>;
>>> +// Unary and binary operators that both read and write EFLAGS as a
>>> side-effect.
>>> +def SDTBinaryArithRWFlags   : SDTypeProfile<1, 3,
>>> +                                  [SDTCisInt<0>, SDTCisSameAs<0,  
>>> 1>,
>>> +                                   SDTCisSameAs<0, 2>, SDTCisVT<3,
>>> i32>]>;
>>> +
>>> def SDTX86BrCond  : SDTypeProfile<0, 3,
>>>                                  [SDTCisVT<0, OtherVT>,
>>>                                   SDTCisVT<1, i8>, SDTCisVT<2, i32>]
>>>
>>>> ;
>>>>
>>> @@ -156,6 +161,8 @@
>>> def X86umul_flag : SDNode<"X86ISD::UMUL", SDTUnaryArithWithFlags>;
>>> def X86inc_flag  : SDNode<"X86ISD::INC",  SDTUnaryArithWithFlags>;
>>> def X86dec_flag  : SDNode<"X86ISD::DEC",  SDTUnaryArithWithFlags>;
>>> +def X86adde_flag : SDNode<"X86ISD::ADDE", SDTBinaryArithRWFlags,
>>> [SDNPInI1]>;
>>> +def X86sube_flag : SDNode<"X86ISD::SUBE", SDTBinaryArithRWFlags,
>>> [SDNPInI1]>;
>>>
>>> def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>;
>>>
>>> @@ -2274,81 +2281,127 @@
>>>
>>> let Uses = [EFLAGS] in {
>>> let isCommutable = 1 in {  // X = ADC Y, Z --> X = ADC Z, Y
>>> -def ADC8rr   : I<0x10, MRMDestReg, (outs GR8:$dst), (ins GR8:$src1,
>>> GR8:$src2),
>>> +def ADC8rr   : I<0x10, MRMDestReg, (outs GR8:$dst),
>>> +                                   (ins GR8:$src1, GR8:$src2),
>>>                 "adc{b}\t{$src2, $dst|$dst, $src2}",
>>> -                 [(set GR8:$dst, (adde GR8:$src1, GR8:$src2))]>;
>>> +                 [(set GR8:$dst, (X86adde_flag GR8:$src1,
>>> GR8:$src2, EFLAGS)),
>>> +                  (implicit EFLAGS)]>;
>>> def ADC16rr  : I<0x11, MRMDestReg, (outs GR16:$dst),
>>>                                   (ins GR16:$src1, GR16:$src2),
>>>                 "adc{w}\t{$src2, $dst|$dst, $src2}",
>>> -                 [(set GR16:$dst, (adde GR16:$src1, GR16:$src2))]>,
>>> OpSize;
>>> +                 [(set GR16:$dst,
>>> +                       (X86adde_flag GR16:$src1, GR16:$src2,
>>> EFLAGS)),
>>> +                  (implicit EFLAGS)]>,
>>> +               OpSize;
>>> def ADC32rr  : I<0x11, MRMDestReg, (outs GR32:$dst),
>>>                                   (ins GR32:$src1, GR32:$src2),
>>>                 "adc{l}\t{$src2, $dst|$dst, $src2}",
>>> -                 [(set GR32:$dst, (adde GR32:$src1, GR32:$src2))]>;
>>> +                 [(set GR32:$dst,
>>> +                       (X86adde_flag GR32:$src1, GR32:$src2,
>>> EFLAGS)),
>>> +                  (implicit EFLAGS)]>;
>>> }
>>> def ADC8rm   : I<0x12, MRMSrcMem , (outs GR8:$dst),
>>>                                   (ins GR8:$src1, i8mem:$src2),
>>>                 "adc{b}\t{$src2, $dst|$dst, $src2}",
>>> -                 [(set GR8:$dst, (adde GR8:$src1, (load addr:
>>> $src2)))]>;
>>> +                 [(set GR8:$dst,
>>> +                       (X86adde_flag GR8:$src1, (load addr:$src2),
>>> EFLAGS)),
>>> +                  (implicit EFLAGS)]>;
>>> def ADC16rm  : I<0x13, MRMSrcMem , (outs GR16:$dst),
>>>                                   (ins GR16:$src1, i16mem:$src2),
>>>                 "adc{w}\t{$src2, $dst|$dst, $src2}",
>>> -                 [(set GR16:$dst, (adde GR16:$src1, (load addr:
>>> $src2)))]>,
>>> +                 [(set GR16:$dst,
>>> +                       (X86adde_flag GR16:$src1, (load addr:$src2),
>>> EFLAGS)),
>>> +                  (implicit EFLAGS)]>,
>>>                 OpSize;
>>> def ADC32rm  : I<0x13, MRMSrcMem , (outs GR32:$dst),
>>>                                   (ins GR32:$src1, i32mem:$src2),
>>>                 "adc{l}\t{$src2, $dst|$dst, $src2}",
>>> -                 [(set GR32:$dst, (adde GR32:$src1, (load addr:
>>> $src2)))]>;
>>> -def ADC8ri   : Ii8<0x80, MRM2r, (outs GR8:$dst), (ins GR8:$src1,
>>> i8imm:$src2),
>>> +                 [(set GR32:$dst,
>>> +                       (X86adde_flag GR32:$src1, (load addr:$src2),
>>> EFLAGS)),
>>> +                  (implicit EFLAGS)]>;
>>> +def ADC8ri   : Ii8<0x80, MRM2r, (outs GR8:$dst),
>>> +                                (ins GR8:$src1, i8imm:$src2),
>>>                    "adc{b}\t{$src2, $dst|$dst, $src2}",
>>> -                 [(set GR8:$dst, (adde GR8:$src1, imm:$src2))]>;
>>> +                 [(set GR8:$dst,
>>> +                       (X86adde_flag GR8:$src1, imm:$src2,  
>>> EFLAGS)),
>>> +                  (implicit EFLAGS)]>;
>>> def ADC16ri  : Ii16<0x81, MRM2r, (outs GR16:$dst),
>>>                                 (ins GR16:$src1, i16imm:$src2),
>>>                    "adc{w}\t{$src2, $dst|$dst, $src2}",
>>> -                 [(set GR16:$dst, (adde GR16:$src1, imm:$src2))]>,
>>> OpSize;
>>> +                 [(set GR16:$dst,
>>> +                       (X86adde_flag GR16:$src1, imm:$src2,  
>>> EFLAGS)),
>>> +                  (implicit EFLAGS)]>, OpSize;
>>> def ADC16ri8 : Ii8<0x83, MRM2r, (outs GR16:$dst),
>>>                                (ins GR16:$src1, i16i8imm:$src2),
>>>                   "adc{w}\t{$src2, $dst|$dst, $src2}",
>>> -                 [(set GR16:$dst, (adde GR16:$src1,
>>> i16immSExt8:$src2))]>,
>>> -                 OpSize;
>>> +                 [(set GR16:$dst,
>>> +                       (X86adde_flag GR16:$src1, i16immSExt8:$src2,
>>> EFLAGS)),
>>> +                  (implicit EFLAGS)]>, OpSize;
>>> def ADC32ri  : Ii32<0x81, MRM2r, (outs GR32:$dst),
>>>                                 (ins GR32:$src1, i32imm:$src2),
>>>                    "adc{l}\t{$src2, $dst|$dst, $src2}",
>>> -                 [(set GR32:$dst, (adde GR32:$src1, imm:$src2))]>;
>>> +                 [(set GR32:$dst,
>>> +                       (X86adde_flag GR32:$src1, imm:$src2,  
>>> EFLAGS)),
>>> +                  (implicit EFLAGS)]>;
>>> def ADC32ri8 : Ii8<0x83, MRM2r, (outs GR32:$dst),
>>>                                (ins GR32:$src1, i32i8imm:$src2),
>>>                   "adc{l}\t{$src2, $dst|$dst, $src2}",
>>> -                 [(set GR32:$dst, (adde GR32:$src1,
>>> i32immSExt8:$src2))]>;
>>> +                 [(set GR32:$dst,
>>> +                       (X86adde_flag GR32:$src1, i32immSExt8:$src2,
>>> EFLAGS)),
>>> +                  (implicit EFLAGS)]>;
>>>
>>> let isTwoAddress = 0 in {
>>> -  def ADC8mr   : I<0x10, MRMDestMem, (outs), (ins i8mem:$dst,
>>> GR8:$src2),
>>> +  def ADC8mr   : I<0x10, MRMDestMem, (outs),
>>> +                                     (ins i8mem:$dst, GR8:$src2),
>>>                   "adc{b}\t{$src2, $dst|$dst, $src2}",
>>> -                   [(store (adde (load addr:$dst), GR8:$src2),  
>>> addr:
>>> $dst)]>;
>>> -  def ADC16mr  : I<0x11, MRMDestMem, (outs), (ins i16mem:$dst,
>>> GR16:$src2),
>>> +                   [(store (X86adde_flag (load addr:$dst),
>>> GR8:$src2, EFLAGS),
>>> +                            addr:$dst),
>>> +                    (implicit EFLAGS)]>;
>>> +  def ADC16mr  : I<0x11, MRMDestMem, (outs),
>>> +                                     (ins i16mem:$dst, GR16:$src2),
>>>                   "adc{w}\t{$src2, $dst|$dst, $src2}",
>>> -                   [(store (adde (load addr:$dst), GR16:$src2),
>>> addr:$dst)]>,
>>> -                   OpSize;
>>> -  def ADC32mr  : I<0x11, MRMDestMem, (outs), (ins i32mem:$dst,
>>> GR32:$src2),
>>> +                   [(store (X86adde_flag (load addr:$dst),
>>> GR16:$src2, EFLAGS),
>>> +                            addr:$dst),
>>> +                    (implicit EFLAGS)]>, OpSize;
>>> +  def ADC32mr  : I<0x11, MRMDestMem, (outs),
>>> +                                     (ins i32mem:$dst, GR32:$src2),
>>>                   "adc{l}\t{$src2, $dst|$dst, $src2}",
>>> -                   [(store (adde (load addr:$dst), GR32:$src2),
>>> addr:$dst)]>;
>>> -  def ADC8mi   : Ii8<0x80, MRM2m, (outs), (ins i8mem:$dst, i8imm:
>>> $src2),
>>> +                   [(store (X86adde_flag (load addr:$dst),
>>> GR32:$src2, EFLAGS),
>>> +                            addr:$dst),
>>> +                    (implicit EFLAGS)]>;
>>> +  def ADC8mi   : Ii8<0x80, MRM2m, (outs),
>>> +                                  (ins i8mem:$dst, i8imm:$src2),
>>>                      "adc{b}\t{$src2, $dst|$dst, $src2}",
>>> -                  [(store (adde (loadi8 addr:$dst), imm:$src2),
>>> addr:$dst)]>;
>>> -  def ADC16mi  : Ii16<0x81, MRM2m, (outs), (ins i16mem:$dst,  
>>> i16imm:
>>> $src2),
>>> +                  [(store (X86adde_flag (loadi8 addr:$dst), imm:
>>> $src2, EFLAGS),
>>> +                           addr:$dst),
>>> +                   (implicit EFLAGS)]>;
>>> +  def ADC16mi  : Ii16<0x81, MRM2m, (outs),
>>> +                                   (ins i16mem:$dst, i16imm:$src2),
>>>                      "adc{w}\t{$src2, $dst|$dst, $src2}",
>>> -                  [(store (adde (loadi16 addr:$dst), imm:$src2),
>>> addr:$dst)]>,
>>> -                  OpSize;
>>> -  def ADC16mi8 : Ii8<0x83, MRM2m, (outs), (ins i16mem:$dst,
>>> i16i8imm :$src2),
>>> +                  [(store (X86adde_flag (loadi16 addr:$dst), imm:
>>> $src2, EFLAGS),
>>> +                           addr:$dst),
>>> +                   (implicit EFLAGS)]>, OpSize;
>>> +  def ADC16mi8 : Ii8<0x83, MRM2m, (outs),
>>> +                                  (ins i16mem:$dst, i16i8imm : 
>>> $src2),
>>>                     "adc{w}\t{$src2, $dst|$dst, $src2}",
>>> -               [(store (adde (load addr:$dst), i16immSExt8:$src2),
>>> addr:$dst)]>,
>>> -               OpSize;
>>> -  def ADC32mi  : Ii32<0x81, MRM2m, (outs), (ins i32mem:$dst,  
>>> i32imm:
>>> $src2),
>>> +                  [(store (X86adde_flag (load addr:$dst),
>>> i16immSExt8:$src2,
>>> +                                        EFLAGS),
>>> +                           addr:$dst),
>>> +                   (implicit EFLAGS)]>, OpSize;
>>> +  def ADC32mi  : Ii32<0x81, MRM2m, (outs),
>>> +                                   (ins i32mem:$dst, i32imm:$src2),
>>>                      "adc{l}\t{$src2, $dst|$dst, $src2}",
>>> -                  [(store (adde (loadi32 addr:$dst), imm:$src2),
>>> addr:$dst)]>;
>>> -  def ADC32mi8 : Ii8<0x83, MRM2m, (outs), (ins i32mem:$dst,
>>> i32i8imm :$src2),
>>> +                  [(store (X86adde_flag (loadi32 addr:$dst), imm:
>>> $src2, EFLAGS),
>>> +                           addr:$dst),
>>> +                   (implicit EFLAGS)]>;
>>> +  def ADC32mi8 : Ii8<0x83, MRM2m, (outs),
>>> +                                  (ins i32mem:$dst, i32i8imm: 
>>> $src2),
>>>                     "adc{l}\t{$src2, $dst|$dst, $src2}",
>>> -               [(store (adde (load addr:$dst), i32immSExt8:$src2),
>>> addr:$dst)]>;
>>> -}
>>> +               [(store (X86adde_flag (load addr:$dst),
>>> i32immSExt8:$src2,
>>> +                                     EFLAGS),
>>> +                        addr:$dst),
>>> +                (implicit EFLAGS)]>;
>>> + }
>>> } // Uses = [EFLAGS]
>>>
>>> // Register-Register Subtraction
>>> @@ -2453,77 +2506,115 @@
>>> def SBB8rr     : I<0x18, MRMDestReg, (outs GR8:$dst),
>>>                                     (ins GR8:$src1, GR8:$src2),
>>>                  "sbb{b}\t{$src2, $dst|$dst, $src2}",
>>> -                 [(set GR8:$dst, (sube GR8:$src1, GR8:$src2))]>;
>>> +                 [(set GR8:$dst, (X86sube_flag GR8:$src1,
>>> GR8:$src2, EFLAGS)),
>>> +                  (implicit EFLAGS)]>;
>>> def SBB16rr    : I<0x19, MRMDestReg, (outs GR16:$dst),
>>>                                     (ins GR16:$src1, GR16:$src2),
>>>                  "sbb{w}\t{$src2, $dst|$dst, $src2}",
>>> -                 [(set GR16:$dst, (sube GR16:$src1, GR16:$src2))]>,
>>> OpSize;
>>> +                 [(set GR16:$dst,
>>> +                       (X86sube_flag GR16:$src1, GR16:$src2,
>>> EFLAGS)),
>>> +                  (implicit EFLAGS)]>, OpSize;
>>> def SBB32rr    : I<0x19, MRMDestReg, (outs GR32:$dst),
>>>                                      (ins GR32:$src1, GR32:$src2),
>>>                  "sbb{l}\t{$src2, $dst|$dst, $src2}",
>>> -                 [(set GR32:$dst, (sube GR32:$src1, GR32:$src2))]>;
>>> +                 [(set GR32:$dst,
>>> +                       (X86sube_flag GR32:$src1, GR32:$src2,
>>> EFLAGS)),
>>> +                  (implicit EFLAGS)]>;
>>>
>>> let isTwoAddress = 0 in {
>>>  def SBB8mr   : I<0x18, MRMDestMem, (outs), (ins i8mem:$dst,
>>> GR8:$src2),
>>>                   "sbb{b}\t{$src2, $dst|$dst, $src2}",
>>> -                   [(store (sube (load addr:$dst), GR8:$src2),  
>>> addr:
>>> $dst)]>;
>>> +                   [(store (X86sube_flag (load addr:$dst),
>>> GR8:$src2, EFLAGS),
>>> +                           addr:$dst),
>>> +                    (implicit EFLAGS)]>;
>>>  def SBB16mr  : I<0x19, MRMDestMem, (outs), (ins i16mem:$dst,
>>> GR16:$src2),
>>>                   "sbb{w}\t{$src2, $dst|$dst, $src2}",
>>> -                   [(store (sube (load addr:$dst), GR16:$src2),
>>> addr:$dst)]>,
>>> +                   [(store (X86sube_flag (load addr:$dst),
>>> GR16:$src2, EFLAGS),
>>> +                            addr:$dst),
>>> +                    (implicit EFLAGS)]>,
>>>                   OpSize;
>>>  def SBB32mr  : I<0x19, MRMDestMem, (outs), (ins i32mem:$dst,
>>> GR32:$src2),
>>>                   "sbb{l}\t{$src2, $dst|$dst, $src2}",
>>> -                   [(store (sube (load addr:$dst), GR32:$src2),
>>> addr:$dst)]>;
>>> +                   [(store (X86sube_flag (load addr:$dst),
>>> GR32:$src2, EFLAGS),
>>> +                           addr:$dst),
>>> +                    (implicit EFLAGS)]>;
>>>  def SBB8mi  : Ii32<0x80, MRM3m, (outs), (ins i8mem:$dst, i8imm:
>>> $src2),
>>>                      "sbb{b}\t{$src2, $dst|$dst, $src2}",
>>> -                   [(store (sube (loadi8 addr:$dst), imm:$src2),
>>> addr:$dst)]>;
>>> +                   [(store (X86sube_flag (loadi8 addr:$dst), imm:
>>> $src2, EFLAGS),
>>> +                           addr:$dst),
>>> +                    (implicit EFLAGS)]>;
>>>  def SBB16mi  : Ii16<0x81, MRM3m, (outs), (ins i16mem:$dst, i16imm:
>>> $src2),
>>>                      "sbb{w}\t{$src2, $dst|$dst, $src2}",
>>> -                  [(store (sube (loadi16 addr:$dst), imm:$src2),
>>> addr:$dst)]>,
>>> +                  [(store (X86sube_flag (loadi16 addr:$dst), imm:
>>> $src2, EFLAGS),
>>> +                          addr:$dst),
>>> +                   (implicit EFLAGS)]>,
>>>                  OpSize;
>>>  def SBB16mi8 : Ii8<0x83, MRM3m, (outs), (ins i16mem:$dst,
>>> i16i8imm :$src2),
>>>                     "sbb{w}\t{$src2, $dst|$dst, $src2}",
>>> -               [(store (sube (load addr:$dst), i16immSExt8:$src2),
>>> addr:$dst)]>,
>>> +               [(store (X86sube_flag (load addr:$dst),
>>> i16immSExt8:$src2,
>>> +                                     EFLAGS),
>>> +                       addr:$dst),
>>> +                (implicit EFLAGS)]>,
>>>               OpSize;
>>>  def SBB32mi  : Ii32<0x81, MRM3m, (outs), (ins i32mem:$dst, i32imm:
>>> $src2),
>>>                      "sbb{l}\t{$src2, $dst|$dst, $src2}",
>>> -                  [(store (sube (loadi32 addr:$dst), imm:$src2),
>>> addr:$dst)]>;
>>> +                  [(store (X86sube_flag (loadi32 addr:$dst), imm:
>>> $src2, EFLAGS),
>>> +                          addr:$dst),
>>> +                   (implicit EFLAGS)]>;
>>>  def SBB32mi8 : Ii8<0x83, MRM3m, (outs), (ins i32mem:$dst,
>>> i32i8imm :$src2),
>>>                     "sbb{l}\t{$src2, $dst|$dst, $src2}",
>>> -               [(store (sube (load addr:$dst), i32immSExt8:$src2),
>>> addr:$dst)]>;
>>> +               [(store (X86sube_flag (load addr:$dst),
>>> i32immSExt8:$src2,
>>> +                                     EFLAGS),
>>> +                       addr:$dst),
>>> +                (implicit EFLAGS)]>;
>>> }
>>> def SBB8rm   : I<0x1A, MRMSrcMem, (outs GR8:$dst), (ins GR8:$src1,
>>> i8mem:$src2),
>>>                    "sbb{b}\t{$src2, $dst|$dst, $src2}",
>>> -                    [(set GR8:$dst, (sube GR8:$src1, (load addr:
>>> $src2)))]>;
>>> +                    [(set GR8:$dst,
>>> +                          (X86sube_flag GR8:$src1, (load addr:
>>> $src2), EFLAGS)),
>>> +                     (implicit EFLAGS)]>;
>>> def SBB16rm  : I<0x1B, MRMSrcMem, (outs GR16:$dst),
>>>                                  (ins GR16:$src1, i16mem:$src2),
>>>                    "sbb{w}\t{$src2, $dst|$dst, $src2}",
>>> -                    [(set GR16:$dst, (sube GR16:$src1, (load addr:
>>> $src2)))]>,
>>> +                    [(set GR16:$dst,
>>> +                         (X86sube_flag GR16:$src1, (load addr:
>>> $src2), EFLAGS)),
>>> +                     (implicit EFLAGS)]>,
>>>                    OpSize;
>>> def SBB32rm  : I<0x1B, MRMSrcMem, (outs GR32:$dst),
>>>                                  (ins GR32:$src1, i32mem:$src2),
>>>                    "sbb{l}\t{$src2, $dst|$dst, $src2}",
>>> -                    [(set GR32:$dst, (sube GR32:$src1, (load addr:
>>> $src2)))]>;
>>> +                    [(set GR32:$dst,
>>> +                         (X86sube_flag GR32:$src1, (load addr:
>>> $src2), EFLAGS)),
>>> +                     (implicit EFLAGS)]>;
>>> def SBB8ri   : Ii8<0x80, MRM3r, (outs GR8:$dst), (ins GR8:$src1,
>>> i8imm:$src2),
>>>                    "sbb{b}\t{$src2, $dst|$dst, $src2}",
>>> -                    [(set GR8:$dst, (sube GR8:$src1, imm:$src2))]>;
>>> +                    [(set GR8:$dst,
>>> +                          (X86sube_flag GR8:$src1, imm:$src2,
>>> EFLAGS)),
>>> +                     (implicit EFLAGS)]>;
>>> def SBB16ri  : Ii16<0x81, MRM3r, (outs GR16:$dst),
>>>                                 (ins GR16:$src1, i16imm:$src2),
>>>                    "sbb{w}\t{$src2, $dst|$dst, $src2}",
>>> -                    [(set GR16:$dst, (sube GR16:$src1, imm:$src2))]
>>>
>>>> , OpSize;
>>>>
>>> +                    [(set GR16:$dst,
>>> +                          (X86sube_flag GR16:$src1, imm:$src2,
>>> EFLAGS)),
>>> +                     (implicit EFLAGS)]>, OpSize;
>>> def SBB16ri8 : Ii8<0x83, MRM3r, (outs GR16:$dst),
>>>                                (ins GR16:$src1, i16i8imm:$src2),
>>>                   "sbb{w}\t{$src2, $dst|$dst, $src2}",
>>> -                   [(set GR16:$dst, (sube GR16:$src1,
>>> i16immSExt8:$src2))]>,
>>> -                   OpSize;
>>> +                   [(set GR16:$dst,
>>> +                         (X86sube_flag GR16:$src1,
>>> i16immSExt8:$src2, EFLAGS)),
>>> +                    (implicit EFLAGS)]>, OpSize;
>>> def SBB32ri  : Ii32<0x81, MRM3r, (outs GR32:$dst),
>>>                                 (ins GR32:$src1, i32imm:$src2),
>>>                    "sbb{l}\t{$src2, $dst|$dst, $src2}",
>>> -                    [(set GR32:$dst, (sube GR32:$src1, imm: 
>>> $src2))]>;
>>> +                    [(set GR32:$dst,
>>> +                          (X86sube_flag GR32:$src1, imm:$src2,
>>> EFLAGS)),
>>> +                     (implicit EFLAGS)]>;
>>> def SBB32ri8 : Ii8<0x83, MRM3r, (outs GR32:$dst),
>>>                                (ins GR32:$src1, i32i8imm:$src2),
>>>                   "sbb{l}\t{$src2, $dst|$dst, $src2}",
>>> -                   [(set GR32:$dst, (sube GR32:$src1,
>>> i32immSExt8:$src2))]>;
>>> +                   [(set GR32:$dst,
>>> +                        (X86sube_flag GR32:$src1,
>>> i32immSExt8:$src2, EFLAGS)),
>>> +                    (implicit EFLAGS)]>;
>>> } // Uses = [EFLAGS]
>>> } // Defs = [EFLAGS]
>>>
>>>
>>> Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=72707&r1=72706&r2=72707&view=diff
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> = 
>>> = 
>>> ====================================================================
>>> --- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original)
>>> +++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Mon Jun  1
>>> 18:27:20 2009
>>> @@ -399,9 +399,13 @@
>>>    } else if (PropList[i]->getName() == "SDNPHasChain") {
>>>      Properties |= 1 << SDNPHasChain;
>>>    } else if (PropList[i]->getName() == "SDNPOutFlag") {
>>> -      Properties |= 1 << SDNPOutFlag;
>>> +      Properties |= 1 << SDNPOutFlag;
>>> +      assert(!(Properties & (1<<SDNPOutI1)) &&
>>> +             "Can't handle OutFlag and OutI1");
>>>    } else if (PropList[i]->getName() == "SDNPInFlag") {
>>>      Properties |= 1 << SDNPInFlag;
>>> +      assert(!(Properties & (1<<SDNPInI1)) &&
>>> +             "Can't handle InFlag and InI1");
>>>    } else if (PropList[i]->getName() == "SDNPOptInFlag") {
>>>      Properties |= 1 << SDNPOptInFlag;
>>>    } else if (PropList[i]->getName() == "SDNPMayStore") {
>>> @@ -412,6 +416,14 @@
>>>      Properties |= 1 << SDNPSideEffect;
>>>    } else if (PropList[i]->getName() == "SDNPMemOperand") {
>>>      Properties |= 1 << SDNPMemOperand;
>>> +    } else if (PropList[i]->getName() == "SDNPInI1") {
>>> +      Properties |= 1 << SDNPInI1;
>>> +      assert(!(Properties & (1<<SDNPInFlag)) &&
>>> +             "Can't handle InFlag and InI1");
>>> +    } else if (PropList[i]->getName() == "SDNPOutI1") {
>>> +      Properties |= 1 << SDNPOutI1;
>>> +      assert(!(Properties & (1<<SDNPOutFlag)) &&
>>> +             "Can't handle OutFlag and OutI1");
>>>    } else {
>>>      cerr << "Unknown SD Node property '" << PropList[i]->getName()
>>>           << "' on node '" << R->getName() << "'!\n";
>>>
>>> Modified: llvm/trunk/utils/TableGen/CodeGenTarget.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.cpp?rev=72707&r1=72706&r2=72707&view=diff
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> = 
>>> = 
>>> ====================================================================
>>> --- llvm/trunk/utils/TableGen/CodeGenTarget.cpp (original)
>>> +++ llvm/trunk/utils/TableGen/CodeGenTarget.cpp Mon Jun  1 18:27:20
>>> 2009
>>> @@ -385,6 +385,13 @@
>>>  return getInstructionSet()- 
>>> >getValueAsBit("isLittleEndianEncoding");
>>> }
>>>
>>> +/// supportsHasI1 - Return whether this target supports the
>>> implicit I1,
>>> +/// rather than Flags, for ADDC/ADDE
>>> +///
>>> +bool CodeGenTarget::supportsHasI1() const {
>>> +  return getInstructionSet()->getValueAsBit("supportsHasI1");
>>> +}
>>> +
>>> //
>>> =
>>> =
>>> =
>>> ----------------------------------------------------------------------=
>>> ==//
>>> // ComplexPattern implementation
>>> //
>>>
>>> Modified: llvm/trunk/utils/TableGen/CodeGenTarget.h
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.h?rev=72707&r1=72706&r2=72707&view=diff
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> = 
>>> = 
>>> ====================================================================
>>> --- llvm/trunk/utils/TableGen/CodeGenTarget.h (original)
>>> +++ llvm/trunk/utils/TableGen/CodeGenTarget.h Mon Jun  1 18:27:20  
>>> 2009
>>> @@ -43,7 +43,9 @@
>>>  SDNPMayLoad,
>>>  SDNPMayStore,
>>>  SDNPSideEffect,
>>> -  SDNPMemOperand
>>> +  SDNPMemOperand,
>>> +  SDNPInI1,
>>> +  SDNPOutI1
>>> };
>>>
>>> // ComplexPattern attributes.
>>> @@ -209,10 +211,12 @@
>>>  void getInstructionsByEnumValue(std::vector<const
>>> CodeGenInstruction*>
>>>
>>> &NumberedInstructions);
>>>
>>> -
>>>  /// isLittleEndianEncoding - are instruction bit patterns defined
>>> as  [0..n]?
>>>  ///
>>>  bool isLittleEndianEncoding() const;
>>> +
>>> +  /// supportsHasI1 - does this target understand HasI1 for ADDE
>>> and ADDC?
>>> +  bool supportsHasI1() const;
>>> };
>>>
>>> /// ComplexPattern - ComplexPattern info, corresponding to the
>>> ComplexPattern
>>>
>>> Modified: llvm/trunk/utils/TableGen/DAGISelEmitter.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelEmitter.cpp?rev=72707&r1=72706&r2=72707&view=diff
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> = 
>>> = 
>>> ====================================================================
>>> --- llvm/trunk/utils/TableGen/DAGISelEmitter.cpp (original)
>>> +++ llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Mon Jun  1 18:27:20
>>> 2009
>>> @@ -670,7 +670,8 @@
>>>        HasChain = true;
>>>        FoldedChains.push_back(std::make_pair(RootName,
>>> CInfo.getNumResults()));
>>>      }
>>> -      if (NodeHasProperty(Child, SDNPOutFlag, CGP)) {
>>> +      if (NodeHasProperty(Child, SDNPOutFlag, CGP) ||
>>> +          NodeHasProperty(Child, SDNPOutI1, CGP)) {
>>>        assert(FoldedFlag.first == "" && FoldedFlag.second == 0 &&
>>>               "Pattern folded multiple nodes which produce flags?");
>>>        FoldedFlag = std::make_pair(RootName,
>>> @@ -969,6 +970,10 @@
>>>        PatternHasProperty(Pattern, SDNPInFlag, CGP);
>>>      bool NodeHasOutFlag = isRoot &&
>>>        PatternHasProperty(Pattern, SDNPOutFlag, CGP);
>>> +      bool NodeHasInI1  = isRoot &&
>>> +        PatternHasProperty(Pattern, SDNPInI1, CGP);
>>> +      bool NodeHasOutI1 = isRoot &&
>>> +        PatternHasProperty(Pattern, SDNPOutI1, CGP);
>>>      bool NodeHasChain = InstPatNode &&
>>>        PatternHasProperty(InstPatNode, SDNPHasChain, CGP);
>>>      bool InputHasChain = isRoot &&
>>> @@ -1054,10 +1059,13 @@
>>>
>>>      // Emit all the chain and CopyToReg stuff.
>>>      bool ChainEmitted = NodeHasChain;
>>> -      if (NodeHasInFlag || HasImpInputs)
>>> +      // InFlag and InI1 cannot both be set (checked in
>>> +      // CodeGenDAGPatterns), so use the same variables for both.
>>> +      if (NodeHasInFlag || HasImpInputs || NodeHasInI1)
>>>        EmitInFlagSelectCode(Pattern, "N", ChainEmitted,
>>>                             InFlagDecled, ResNodeDecled, true);
>>> -      if (NodeHasOptInFlag || NodeHasInFlag || HasImpInputs) {
>>> +      if (NodeHasOptInFlag || NodeHasInFlag || HasImpInputs ||
>>> +          NodeHasInI1) {
>>>        if (!InFlagDecled) {
>>>          emitCode("SDValue InFlag(0, 0);");
>>>          InFlagDecled = true;
>>> @@ -1113,7 +1121,7 @@
>>>      }
>>>      if (NodeHasChain)
>>>        Code += ", MVT::Other";
>>> -      if (NodeHasOutFlag)
>>> +      if (NodeHasOutFlag || (NodeHasOutI1 && !CGT.supportsHasI1()))
>>>        Code += ", MVT::Flag";
>>>
>>>      // Inputs.
>>> @@ -1173,7 +1181,8 @@
>>>        }
>>>        Code += ", &Ops" + utostr(OpsNo) + "[0], Ops" + utostr
>>> (OpsNo) +
>>>          ".size()";
>>> -      } else if (NodeHasInFlag || NodeHasOptInFlag || HasImpInputs)
>>> +      } else if (NodeHasInFlag || NodeHasOptInFlag ||  
>>> HasImpInputs ||
>>> +                 NodeHasInI1)
>>>        AllOps.push_back("InFlag");
>>>
>>>      unsigned NumOps = AllOps.size();
>>> @@ -1207,7 +1216,7 @@
>>>        NodeOps.push_back("Tmp" + utostr(ResNo));
>>>      } else {
>>>
>>> -      if (NodeHasOutFlag) {
>>> +      if (NodeHasOutFlag || NodeHasOutI1) {
>>>        if (!InFlagDecled) {
>>>          After.push_back("SDValue InFlag(ResNode, " +
>>>                          utostr(NumResults+NumDstRegs+(unsigned)
>>> NodeHasChain) +
>>> @@ -1228,13 +1237,15 @@
>>>                             utostr(NumResults+NumDstRegs) + ")");
>>>      }
>>>
>>> -      if (NodeHasOutFlag) {
>>> +      if (NodeHasOutFlag || NodeHasOutI1) {
>>>        if (FoldedFlag.first != "") {
>>> -          ReplaceFroms.push_back("SDValue(" + FoldedFlag.first +
>>> ".getNode(), " +
>>> +          ReplaceFroms.push_back("SDValue(" + FoldedFlag.first +
>>> +                                 ".getNode(), " +
>>>                                 utostr(FoldedFlag.second) + ")");
>>>          ReplaceTos.push_back("InFlag");
>>>        } else {
>>> -          assert(NodeHasProperty(Pattern, SDNPOutFlag, CGP));
>>> +          assert(NodeHasProperty(Pattern, SDNPOutFlag, CGP) ||
>>> +                 NodeHasProperty(Pattern, SDNPOutI1, CGP));
>>>          ReplaceFroms.push_back("SDValue(N.getNode(), " +
>>>                                 utostr(NumPatResults + (unsigned)
>>> InputHasChain)
>>>                                 + ")");
>>> @@ -1251,7 +1262,8 @@
>>>      }
>>>
>>>      // User does not expect the instruction would produce a chain!
>>> -      if ((!InputHasChain && NodeHasChain) && NodeHasOutFlag) {
>>> +      if ((!InputHasChain && NodeHasChain) &&
>>> +          (NodeHasOutFlag || NodeHasOutI1)) {
>>>        ;
>>>      } else if (InputHasChain && !NodeHasChain) {
>>>        // One of the inner node produces a chain.
>>> @@ -1391,6 +1403,8 @@
>>>    unsigned OpNo =
>>>      (unsigned) NodeHasProperty(N, SDNPHasChain, CGP);
>>>    bool HasInFlag = NodeHasProperty(N, SDNPInFlag, CGP);
>>> +    bool HasInI1 = NodeHasProperty(N, SDNPInI1, CGP);
>>> +    bool InFlagDefined = false;
>>>    for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i, +
>>> +OpNo) {
>>>      TreePatternNode *Child = N->getChild(i);
>>>      if (!Child->isLeaf()) {
>>> @@ -1424,21 +1438,41 @@
>>>                emitCode("SDValue InFlag(0, 0);");
>>>                InFlagDecled = true;
>>>              }
>>> -              std::string Decl = (!ResNodeDecled) ? "SDNode *" :  
>>> "";
>>> -              emitCode(Decl + "ResNode = CurDAG->getCopyToReg(" +
>>> ChainName +
>>> +              if (HasInI1) {
>>> +                if (!ResNodeDecled) {
>>> +                  emitCode("SDNode * ResNode;");
>>> +                }
>>> +                if (T.supportsHasI1())
>>> +                  emitCode("ResNode = CurDAG->getCopyToReg(" +
>>> ChainName +
>>> +                         ", " + RootName + ".getDebugLoc()" +
>>> +                         ", " + getEnumName(RVT) +
>>> +                         ", " + getQualifiedName(RR) +
>>> +                         ", " +  RootName + utostr(OpNo) +
>>> ").getNode();");
>>> +                else
>>> +                  emitCode("ResNode = CurDAG->getCopyToReg(" +
>>> ChainName +
>>> +                         ", " + RootName + ".getDebugLoc()" +
>>> +                         ", " + getQualifiedName(RR) +
>>> +                         ", " +  RootName + utostr(OpNo) +
>>> +                         ", InFlag).getNode();");
>>> +                InFlagDefined = true;
>>> +              } else {
>>> +                std::string Decl = (!ResNodeDecled) ? "SDNode *" :
>>> "";
>>> +                emitCode(Decl + "ResNode = CurDAG->getCopyToReg(" +
>>> ChainName +
>>>                       ", " + RootName + ".getDebugLoc()" +
>>>                       ", " + getQualifiedName(RR) +
>>> -                       ", " +  RootName + utostr(OpNo) + ",
>>> InFlag).getNode();");
>>> -              ResNodeDecled = true;
>>> +                       ", " +  RootName + utostr(OpNo) +
>>> +                       ", InFlag).getNode();");
>>> +              }
>>>              emitCode(ChainName + " = SDValue(ResNode, 0);");
>>>              emitCode("InFlag = SDValue(ResNode, 1);");
>>> +              ResNodeDecled = true;
>>>            }
>>>          }
>>>        }
>>>      }
>>>    }
>>>
>>> -    if (HasInFlag) {
>>> +    if (HasInFlag || (HasInI1 && !InFlagDefined)) {
>>>      if (!InFlagDecled) {
>>>        emitCode("SDValue InFlag = " + RootName +
>>>               ".getOperand(" + utostr(OpNo) + ");");
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list