diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 67 | 
1 files changed, 45 insertions, 22 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index e2862f6200c..c7b383a8be4 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -30939,11 +30939,40 @@ static bool checkBoolTestAndOrSetCCCombine(SDValue Cond, X86::CondCode &CC0,    return true;  } +// When legalizing carry, we create carries via add X, -1 +// If that comes from an actual carry, via setcc, we use the +// carry directly. +static SDValue combineCarryThroughADD(SDValue EFLAGS) { +  if (EFLAGS.getOpcode() == X86ISD::ADD) { +    if (isAllOnesConstant(EFLAGS.getOperand(1))) { +      SDValue Carry = EFLAGS.getOperand(0); +      while (Carry.getOpcode() == ISD::TRUNCATE || +             Carry.getOpcode() == ISD::ZERO_EXTEND || +             Carry.getOpcode() == ISD::SIGN_EXTEND || +             Carry.getOpcode() == ISD::ANY_EXTEND || +             (Carry.getOpcode() == ISD::AND && +              isOneConstant(Carry.getOperand(1)))) +        Carry = Carry.getOperand(0); +      if (Carry.getOpcode() == X86ISD::SETCC || +          Carry.getOpcode() == X86ISD::SETCC_CARRY) { +        if (Carry.getConstantOperandVal(0) == X86::COND_B) +          return Carry.getOperand(1); +      } +    } +  } + +  return SDValue(); +} +  /// Optimize an EFLAGS definition used according to the condition code \p CC  /// into a simpler EFLAGS value, potentially returning a new \p CC and replacing  /// uses of chain values.  static SDValue combineSetCCEFLAGS(SDValue EFLAGS, X86::CondCode &CC,                                    SelectionDAG &DAG) { +  if (CC == X86::COND_B) +    if (SDValue Flags = combineCarryThroughADD(EFLAGS)) +      return Flags; +    if (SDValue R = checkBoolTestSetCCCombine(EFLAGS, CC))      return R;    return combineSetCCAtomicArith(EFLAGS, CC, DAG); @@ -34987,27 +35016,13 @@ static SDValue combineSIntToFP(SDNode *N, SelectionDAG &DAG,    return SDValue();  } -// Optimize RES, EFLAGS = X86ISD::ADD LHS, RHS -static SDValue combineX86ADD(SDNode *N, SelectionDAG &DAG, -                             X86TargetLowering::DAGCombinerInfo &DCI) { -  // When legalizing carry, we create carries via add X, -1 -  // If that comes from an actual carry, via setcc, we use the -  // carry directly. -  if (isAllOnesConstant(N->getOperand(1)) && N->hasAnyUseOfValue(1)) { -    SDValue Carry = N->getOperand(0); -    while (Carry.getOpcode() == ISD::TRUNCATE || -           Carry.getOpcode() == ISD::ZERO_EXTEND || -           Carry.getOpcode() == ISD::SIGN_EXTEND || -           Carry.getOpcode() == ISD::ANY_EXTEND || -           (Carry.getOpcode() == ISD::AND && -            isOneConstant(Carry.getOperand(1)))) -      Carry = Carry.getOperand(0); - -    if (Carry.getOpcode() == X86ISD::SETCC || -        Carry.getOpcode() == X86ISD::SETCC_CARRY) { -      if (Carry.getConstantOperandVal(0) == X86::COND_B) -        return DCI.CombineTo(N, SDValue(N, 0), Carry.getOperand(1)); -    } +static SDValue combineSBB(SDNode *N, SelectionDAG &DAG) { +  if (SDValue Flags = combineCarryThroughADD(N->getOperand(2))) { +    MVT VT = N->getSimpleValueType(0); +    SDVTList VTs = DAG.getVTList(VT, MVT::i32); +    return DAG.getNode(X86ISD::SBB, SDLoc(N), VTs, +                       N->getOperand(0), N->getOperand(1), +                       Flags);    }    return SDValue(); @@ -35036,6 +35051,14 @@ static SDValue combineADC(SDNode *N, SelectionDAG &DAG,      return DCI.CombineTo(N, Res1, CarryOut);    } +  if (SDValue Flags = combineCarryThroughADD(N->getOperand(2))) { +    MVT VT = N->getSimpleValueType(0); +    SDVTList VTs = DAG.getVTList(VT, MVT::i32); +    return DAG.getNode(X86ISD::ADC, SDLoc(N), VTs, +                       N->getOperand(0), N->getOperand(1), +                       Flags); +  } +    return SDValue();  } @@ -35721,7 +35744,7 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,    case X86ISD::CMOV:        return combineCMov(N, DAG, DCI, Subtarget);    case ISD::ADD:            return combineAdd(N, DAG, Subtarget);    case ISD::SUB:            return combineSub(N, DAG, Subtarget); -  case X86ISD::ADD:         return combineX86ADD(N, DAG, DCI); +  case X86ISD::SBB:         return combineSBB(N, DAG);    case X86ISD::ADC:         return combineADC(N, DAG, DCI);    case ISD::MUL:            return combineMul(N, DAG, DCI, Subtarget);    case ISD::SHL:  | 

