[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 14:20:44 PDT 2009


On Jun 2, 2009, at 2:09 PMPDT, Evan Cheng wrote:

>
> On Jun 2, 2009, at 11:23 AM, Dale Johannesen wrote:
>
>>
>> On Jun 2, 2009, at 11:00 AMPDT, 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
>> I assume you mean MVT::Flag
>>> and change ADDC / ADDE to use MVT::i1 to
>>> represent the flag value.
>>
>> Offhand I don't like that, it means a fair amount of parallel but
>> subtly different code in the target-independent parts and calls for
>> changing all non-x86 BEs to use addc_flag.   This way, the target-
>> independent code is clean and the complexities are all in TableGen.
>> I agree HasI1 is not a thing of beauty; let me think about it more.
>
> But doesn't this mean ADDC produces a MVT::Flag for some targets but
> MVT::i1 for others? How would that work?

In the target-independent parts ADDC produces MVT::i1.  When we select  
to target-dependent code it may get lowered to produce either i1 (as  
it has been legalized for the target) or Flag depending on what the  
target is ready for.  The TableGen code that does this is pretty ugly,  
and hopefully that's a temporary situation; OTOH, the ugliness is  
pretty well limited to TableGen.  Most targets don't have an analog of  
(implicit EFLAGS), and I'm not familiar with all the architectures, so  
I didn't think it practical to change all the other targets at once.

>> This is not far off Eli's suggestion of hijacking UADDO to replace
>> ADDC with i1, what do you think of that?
>
> I suppose that's possible because they do seem similar.
>
> Evan
>
>>
>>> 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
>
> _______________________________________________
> 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