diff options
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp')
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 1061 |
1 files changed, 0 insertions, 1061 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index ea605e1eb2e..945e764a2d2 100644 --- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -69,19 +69,6 @@ using namespace llvm; #define DEBUG_TYPE "ppc-codegen" -STATISTIC(NumSextSetcc, - "Number of (sext(setcc)) nodes expanded into GPR sequence."); -STATISTIC(NumZextSetcc, - "Number of (zext(setcc)) nodes expanded into GPR sequence."); -STATISTIC(SignExtensionsAdded, - "Number of sign extensions for compare inputs added."); -STATISTIC(ZeroExtensionsAdded, - "Number of zero extensions for compare inputs added."); -STATISTIC(NumLogicOpsOnComparison, - "Number of logical ops on i1 values calculated in GPR."); -STATISTIC(OmittedForNonExtendUses, - "Number of compares not eliminated as they have non-extending uses."); - // FIXME: Remove this once the bug has been fixed! cl::opt<bool> ANDIGlueBug("expose-ppc-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden); @@ -276,46 +263,7 @@ namespace { #include "PPCGenDAGISel.inc" private: - // Conversion type for interpreting results of a 32-bit instruction as - // a 64-bit value or vice versa. - enum ExtOrTruncConversion { Ext, Trunc }; - - // Modifiers to guide how an ISD::SETCC node's result is to be computed - // in a GPR. - // ZExtOrig - use the original condition code, zero-extend value - // ZExtInvert - invert the condition code, zero-extend value - // SExtOrig - use the original condition code, sign-extend value - // SExtInvert - invert the condition code, sign-extend value - enum SetccInGPROpts { ZExtOrig, ZExtInvert, SExtOrig, SExtInvert }; - - // Comparisons against zero to emit GPR code sequences for. Each of these - // sequences may need to be emitted for two or more equivalent patterns. - // For example (a >= 0) == (a > -1). The direction of the comparison (</>) - // matters as well as the extension type: sext (-1/0), zext (1/0). - // GEZExt - (zext (LHS >= 0)) - // GESExt - (sext (LHS >= 0)) - // LEZExt - (zext (LHS <= 0)) - // LESExt - (sext (LHS <= 0)) - enum ZeroCompare { GEZExt, GESExt, LEZExt, LESExt }; - bool trySETCC(SDNode *N); - bool tryEXTEND(SDNode *N); - bool tryLogicOpOfCompares(SDNode *N); - SDValue computeLogicOpInGPR(SDValue LogicOp); - SDValue signExtendInputIfNeeded(SDValue Input); - SDValue zeroExtendInputIfNeeded(SDValue Input); - SDValue addExtOrTrunc(SDValue NatWidthRes, ExtOrTruncConversion Conv); - SDValue getCompoundZeroComparisonInGPR(SDValue LHS, SDLoc dl, - ZeroCompare CmpTy); - SDValue get32BitZExtCompare(SDValue LHS, SDValue RHS, ISD::CondCode CC, - int64_t RHSValue, SDLoc dl); - SDValue get32BitSExtCompare(SDValue LHS, SDValue RHS, ISD::CondCode CC, - int64_t RHSValue, SDLoc dl); - SDValue get64BitZExtCompare(SDValue LHS, SDValue RHS, ISD::CondCode CC, - int64_t RHSValue, SDLoc dl); - SDValue get64BitSExtCompare(SDValue LHS, SDValue RHS, ISD::CondCode CC, - int64_t RHSValue, SDLoc dl); - SDValue getSETCCInGPR(SDValue Compare, SetccInGPROpts ConvOpts); void PeepholePPC64(); void PeepholePPC64ZExt(); @@ -2529,1000 +2477,6 @@ bool PPCDAGToDAGISel::trySETCC(SDNode *N) { return true; } -// Is this opcode a bitwise logical operation? -static bool isLogicOp(unsigned Opc) { - return Opc == ISD::AND || Opc == ISD::OR || Opc == ISD::XOR; -} - -/// If this node is a sign/zero extension of an integer comparison, -/// it can usually be computed in GPR's rather than using comparison -/// instructions and ISEL. We only do this on 64-bit targets for now -/// as the code is specialized for 64-bit (it uses 64-bit instructions -/// and assumes 64-bit registers). -bool PPCDAGToDAGISel::tryEXTEND(SDNode *N) { - if (TM.getOptLevel() == CodeGenOpt::None || !TM.isPPC64()) - return false; - assert((N->getOpcode() == ISD::ZERO_EXTEND || - N->getOpcode() == ISD::SIGN_EXTEND) && - "Expecting a zero/sign extend node!"); - - SDValue WideRes; - // If we are zero-extending the result of a logical operation on i1 - // values, we can keep the values in GPRs. - if (isLogicOp(N->getOperand(0).getOpcode()) && - N->getOperand(0).getValueType() == MVT::i1 && - N->getOpcode() == ISD::ZERO_EXTEND) - WideRes = computeLogicOpInGPR(N->getOperand(0)); - else if (N->getOperand(0).getOpcode() != ISD::SETCC) - return false; - else - WideRes = - getSETCCInGPR(N->getOperand(0), - N->getOpcode() == ISD::SIGN_EXTEND ? - SetccInGPROpts::SExtOrig : SetccInGPROpts::ZExtOrig); - - if (!WideRes) - return false; - - SDLoc dl(N); - bool Input32Bit = WideRes.getValueType() == MVT::i32; - bool Output32Bit = N->getValueType(0) == MVT::i32; - - NumSextSetcc += N->getOpcode() == ISD::SIGN_EXTEND ? 1 : 0; - NumZextSetcc += N->getOpcode() == ISD::SIGN_EXTEND ? 0 : 1; - - SDValue ConvOp = WideRes; - if (Input32Bit != Output32Bit) - ConvOp = addExtOrTrunc(WideRes, Input32Bit ? ExtOrTruncConversion::Ext : - ExtOrTruncConversion::Trunc); - ReplaceNode(N, ConvOp.getNode()); - - return true; -} - -// Lower a logical operation on i1 values into a GPR sequence if possible. -// The result can be kept in a GPR if requested. -// Three types of inputs can be handled: -// - SETCC -// - TRUNCATE -// - Logical operation (AND/OR/XOR) -// There is also a special case that is handled (namely a complement operation -// achieved with xor %a, -1). -SDValue PPCDAGToDAGISel::computeLogicOpInGPR(SDValue LogicOp) { - assert(isLogicOp(LogicOp.getOpcode()) && - "Can only handle logic operations here."); - assert(LogicOp.getValueType() == MVT::i1 && - "Can only handle logic operations on i1 values here."); - SDLoc dl(LogicOp); - SDValue LHS, RHS; - - // Special case: xor %a, -1 - bool IsBitwiseNegation = isBitwiseNot(LogicOp); - - // Produces a GPR sequence for each operand of the binary logic operation. - // For SETCC, it produces the respective comparison, for TRUNCATE it truncates - // the value in a GPR and for logic operations, it will recursively produce - // a GPR sequence for the operation. - auto getLogicOperand = [&] (SDValue Operand) -> SDValue { - unsigned OperandOpcode = Operand.getOpcode(); - if (OperandOpcode == ISD::SETCC) - return getSETCCInGPR(Operand, SetccInGPROpts::ZExtOrig); - else if (OperandOpcode == ISD::TRUNCATE) { - SDValue InputOp = Operand.getOperand(0); - EVT InVT = InputOp.getValueType(); - return - SDValue(CurDAG->getMachineNode(InVT == MVT::i32 ? PPC::RLDICL_32 : - PPC::RLDICL, dl, InVT, InputOp, - getI64Imm(0, dl), getI64Imm(63, dl)), 0); - } else if (isLogicOp(OperandOpcode)) - return computeLogicOpInGPR(Operand); - return SDValue(); - }; - LHS = getLogicOperand(LogicOp.getOperand(0)); - RHS = getLogicOperand(LogicOp.getOperand(1)); - - // If a GPR sequence can't be produced for the LHS we can't proceed. - // Not producing a GPR sequence for the RHS is only a problem if this isn't - // a bitwise negation operation. - if (!LHS || (!RHS && !IsBitwiseNegation)) - return SDValue(); - - NumLogicOpsOnComparison++; - - // We will use the inputs as 64-bit values. - if (LHS.getValueType() == MVT::i32) - LHS = addExtOrTrunc(LHS, ExtOrTruncConversion::Ext); - if (!IsBitwiseNegation && RHS.getValueType() == MVT::i32) - RHS = addExtOrTrunc(RHS, ExtOrTruncConversion::Ext); - - unsigned NewOpc; - switch (LogicOp.getOpcode()) { - default: llvm_unreachable("Unknown logic operation."); - case ISD::AND: NewOpc = PPC::AND8; break; - case ISD::OR: NewOpc = PPC::OR8; break; - case ISD::XOR: NewOpc = PPC::XOR8; break; - } - - if (IsBitwiseNegation) { - RHS = getI64Imm(1, dl); - NewOpc = PPC::XORI8; - } - - return SDValue(CurDAG->getMachineNode(NewOpc, dl, MVT::i64, LHS, RHS), 0); - -} - -/// Try performing logical operations on results of comparisons in GPRs. -/// It is typically preferred from a performance perspective over performing -/// the operations on individual bits in the CR. We only do this on 64-bit -/// targets for now as the code is specialized for 64-bit (it uses 64-bit -/// instructions and assumes 64-bit registers). -bool PPCDAGToDAGISel::tryLogicOpOfCompares(SDNode *N) { - if (TM.getOptLevel() == CodeGenOpt::None || !TM.isPPC64()) - return false; - if (N->getValueType(0) != MVT::i1) - return false; - assert(isLogicOp(N->getOpcode()) && - "Expected a logic operation on setcc results."); - SDValue LoweredLogical = computeLogicOpInGPR(SDValue(N, 0)); - if (!LoweredLogical) - return false; - - SDLoc dl(N); - bool IsBitwiseNegate = LoweredLogical.getMachineOpcode() == PPC::XORI8; - unsigned SubRegToExtract = IsBitwiseNegate ? PPC::sub_eq : PPC::sub_gt; - SDValue CR0Reg = CurDAG->getRegister(PPC::CR0, MVT::i32); - SDValue LHS = LoweredLogical.getOperand(0); - SDValue RHS = LoweredLogical.getOperand(1); - SDValue WideOp; - SDValue OpToConvToRecForm; - - // Look through any 32-bit to 64-bit implicit extend nodes to find the opcode - // that is input to the XORI. - if (IsBitwiseNegate && - LoweredLogical.getOperand(0).getMachineOpcode() == PPC::INSERT_SUBREG) - OpToConvToRecForm = LoweredLogical.getOperand(0).getOperand(1); - else if (IsBitwiseNegate) - // If the input to the XORI isn't an extension, that's what we're after. - OpToConvToRecForm = LoweredLogical.getOperand(0); - else - // If this is not an XORI, it is a reg-reg logical op and we can convert it - // to record-form. - OpToConvToRecForm = LoweredLogical; - - // Get the record-form version of the node we're looking to use to get the - // CR result from. - uint16_t NonRecOpc = OpToConvToRecForm.getMachineOpcode(); - int NewOpc = PPCInstrInfo::getRecordFormOpcode(NonRecOpc); - - // Convert the right node to record-form. This is either the logical we're - // looking at or it is the input node to the negation (if we're looking at - // a bitwise negation). - if (NewOpc != -1 && IsBitwiseNegate) { - // The input to the XORI has a record-form. Use it. - assert(LoweredLogical.getConstantOperandVal(1) == 1 && - "Expected a PPC::XORI8 only for bitwise negation."); - // Emit the record-form instruction. - std::vector<SDValue> Ops; - for (int i = 0, e = OpToConvToRecForm.getNumOperands(); i < e; i++) - Ops.push_back(OpToConvToRecForm.getOperand(i)); - - WideOp = - SDValue(CurDAG->getMachineNode(NewOpc, dl, - OpToConvToRecForm.getValueType(), - MVT::Glue, Ops), 0); - } else { - assert((NewOpc != -1 || !IsBitwiseNegate) && - "No record form available for AND8/OR8/XOR8?"); - WideOp = - SDValue(CurDAG->getMachineNode(NewOpc == -1 ? PPC::ANDIo8 : NewOpc, dl, - MVT::i64, MVT::Glue, LHS, RHS), 0); - } - - // Select this node to a single bit from CR0 set by the record-form node - // just created. For bitwise negation, use the EQ bit which is the equivalent - // of negating the result (i.e. it is a bit set when the result of the - // operation is zero). - SDValue SRIdxVal = - CurDAG->getTargetConstant(SubRegToExtract, dl, MVT::i32); - SDValue CRBit = - SDValue(CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, - MVT::i1, CR0Reg, SRIdxVal, - WideOp.getValue(1)), 0); - ReplaceNode(N, CRBit.getNode()); - return true; -} - -/// If the value isn't guaranteed to be sign-extended to 64-bits, extend it. -/// Otherwise just reinterpret it as a 64-bit value. -/// Useful when emitting comparison code for 32-bit values without using -/// the compare instruction (which only considers the lower 32-bits). -SDValue PPCDAGToDAGISel::signExtendInputIfNeeded(SDValue Input) { - assert(Input.getValueType() == MVT::i32 && - "Can only sign-extend 32-bit values here."); - unsigned Opc = Input.getOpcode(); - - // The value was sign extended and then truncated to 32-bits. No need to - // sign extend it again. - if (Opc == ISD::TRUNCATE && - (Input.getOperand(0).getOpcode() == ISD::AssertSext || - Input.getOperand(0).getOpcode() == ISD::SIGN_EXTEND)) - return addExtOrTrunc(Input, ExtOrTruncConversion::Ext); - - LoadSDNode *InputLoad = dyn_cast<LoadSDNode>(Input); - // The input is a sign-extending load. No reason to sign-extend. - if (InputLoad && InputLoad->getExtensionType() == ISD::SEXTLOAD) - return addExtOrTrunc(Input, ExtOrTruncConversion::Ext); - - ConstantSDNode *InputConst = dyn_cast<ConstantSDNode>(Input); - // We don't sign-extend constants and already sign-extended values. - if (InputConst || Opc == ISD::AssertSext || Opc == ISD::SIGN_EXTEND_INREG || - Opc == ISD::SIGN_EXTEND) - return addExtOrTrunc(Input, ExtOrTruncConversion::Ext); - - SDLoc dl(Input); - SignExtensionsAdded++; - return SDValue(CurDAG->getMachineNode(PPC::EXTSW_32_64, dl, - MVT::i64, Input), 0); -} - -/// If the value isn't guaranteed to be zero-extended to 64-bits, extend it. -/// Otherwise just reinterpret it as a 64-bit value. -/// Useful when emitting comparison code for 32-bit values without using -/// the compare instruction (which only considers the lower 32-bits). -SDValue PPCDAGToDAGISel::zeroExtendInputIfNeeded(SDValue Input) { - assert(Input.getValueType() == MVT::i32 && - "Can only zero-extend 32-bit values here."); - unsigned Opc = Input.getOpcode(); - - // The only condition under which we can omit the actual extend instruction: - // - The value has already been zero-extended - // - The value is a positive constant - // - The value comes from a load that isn't a sign-extending load - // An ISD::TRUNCATE needs to be zero-extended unless it is fed by a zext. - bool IsTruncateOfZExt = Opc == ISD::TRUNCATE && - (Input.getOperand(0).getOpcode() == ISD::AssertZext || - Input.getOperand(0).getOpcode() == ISD::ZERO_EXTEND); - if (Opc == ISD::AssertZext || Opc == ISD::ZERO_EXTEND || IsTruncateOfZExt) - return addExtOrTrunc(Input, ExtOrTruncConversion::Ext); - - ConstantSDNode *InputConst = dyn_cast<ConstantSDNode>(Input); - if (InputConst && InputConst->getSExtValue() >= 0) - return addExtOrTrunc(Input, ExtOrTruncConversion::Ext); - - LoadSDNode *InputLoad = dyn_cast<LoadSDNode>(Input); - // The input is a load that doesn't sign-extend (it will be zero-extended). - if (InputLoad && InputLoad->getExtensionType() != ISD::SEXTLOAD) - return addExtOrTrunc(Input, ExtOrTruncConversion::Ext); - - // None of the above, need to zero-extend. - SDLoc dl(Input); - ZeroExtensionsAdded++; - return SDValue(CurDAG->getMachineNode(PPC::RLDICL_32_64, dl, MVT::i64, Input, - getI64Imm(0, dl), getI64Imm(32, dl)), - 0); -} - -// Handle a 32-bit value in a 64-bit register and vice-versa. These are of -// course not actual zero/sign extensions that will generate machine code, -// they're just a way to reinterpret a 32 bit value in a register as a -// 64 bit value and vice-versa. -SDValue PPCDAGToDAGISel::addExtOrTrunc(SDValue NatWidthRes, - ExtOrTruncConversion Conv) { - SDLoc dl(NatWidthRes); - - // For reinterpreting 32-bit values as 64 bit values, we generate - // INSERT_SUBREG IMPLICIT_DEF:i64, <input>, TargetConstant:i32<1> - if (Conv == ExtOrTruncConversion::Ext) { - SDValue ImDef(CurDAG->getMachineNode(PPC::IMPLICIT_DEF, dl, MVT::i64), 0); - SDValue SubRegIdx = - CurDAG->getTargetConstant(PPC::sub_32, dl, MVT::i32); - return SDValue(CurDAG->getMachineNode(PPC::INSERT_SUBREG, dl, MVT::i64, - ImDef, NatWidthRes, SubRegIdx), 0); - } - - assert(Conv == ExtOrTruncConversion::Trunc && - "Unknown convertion between 32 and 64 bit values."); - // For reinterpreting 64-bit values as 32-bit values, we just need to - // EXTRACT_SUBREG (i.e. extract the low word). - SDValue SubRegIdx = - CurDAG->getTargetConstant(PPC::sub_32, dl, MVT::i32); - return SDValue(CurDAG->getMachineNode(PPC::EXTRACT_SUBREG, dl, MVT::i32, - NatWidthRes, SubRegIdx), 0); -} - -// Produce a GPR sequence for compound comparisons (<=, >=) against zero. -// Handle both zero-extensions and sign-extensions. -SDValue PPCDAGToDAGISel::getCompoundZeroComparisonInGPR(SDValue LHS, SDLoc dl, - ZeroCompare CmpTy) { - EVT InVT = LHS.getValueType(); - bool Is32Bit = InVT == MVT::i32; - SDValue ToExtend; - - // Produce the value that needs to be either zero or sign extended. - switch (CmpTy) { - case ZeroCompare::GEZExt: - case ZeroCompare::GESExt: - ToExtend = SDValue(CurDAG->getMachineNode(Is32Bit ? PPC::NOR : PPC::NOR8, - dl, InVT, LHS, LHS), 0); - break; - case ZeroCompare::LEZExt: - case ZeroCompare::LESExt: { - if (Is32Bit) { - // Upper 32 bits cannot be undefined for this sequence. - LHS = signExtendInputIfNeeded(LHS); - SDValue Neg = - SDValue(CurDAG->getMachineNode(PPC::NEG8, dl, MVT::i64, LHS), 0); - ToExtend = - SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, - Neg, getI64Imm(1, dl), - getI64Imm(63, dl)), 0); - } else { - SDValue Addi = - SDValue(CurDAG->getMachineNode(PPC::ADDI8, dl, MVT::i64, LHS, - getI64Imm(~0ULL, dl)), 0); - ToExtend = SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64, - Addi, LHS), 0); - } - break; - } - } - - // For 64-bit sequences, the extensions are the same for the GE/LE cases. - if (!Is32Bit && - (CmpTy == ZeroCompare::GEZExt || CmpTy == ZeroCompare::LEZExt)) - return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, - ToExtend, getI64Imm(1, dl), - getI64Imm(63, dl)), 0); - if (!Is32Bit && - (CmpTy == ZeroCompare::GESExt || CmpTy == ZeroCompare::LESExt)) - return SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64, ToExtend, - getI64Imm(63, dl)), 0); - - assert(Is32Bit && "Should have handled the 32-bit sequences above."); - // For 32-bit sequences, the extensions differ between GE/LE cases. - switch (CmpTy) { - case ZeroCompare::GEZExt: { - SDValue ShiftOps[] = - { ToExtend, getI32Imm(1, dl), getI32Imm(31, dl), getI32Imm(31, dl) }; - return SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32, - ShiftOps), 0); - } - case ZeroCompare::GESExt: - return SDValue(CurDAG->getMachineNode(PPC::SRAWI, dl, MVT::i32, ToExtend, - getI32Imm(31, dl)), 0); - case ZeroCompare::LEZExt: - return SDValue(CurDAG->getMachineNode(PPC::XORI8, dl, MVT::i64, ToExtend, - getI32Imm(1, dl)), 0); - case ZeroCompare::LESExt: - return SDValue(CurDAG->getMachineNode(PPC::ADDI8, dl, MVT::i64, ToExtend, - getI32Imm(-1, dl)), 0); - } - - // The above case covers all the enumerators so it can't have a default clause - // to avoid compiler warnings. - llvm_unreachable("Unknown zero-comparison type."); -} - -/// Produces a zero-extended result of comparing two 32-bit values according to -/// the passed condition code. -SDValue PPCDAGToDAGISel::get32BitZExtCompare(SDValue LHS, SDValue RHS, - ISD::CondCode CC, - int64_t RHSValue, SDLoc dl) { - bool IsRHSZero = RHSValue == 0; - bool IsRHSOne = RHSValue == 1; - bool IsRHSNegOne = RHSValue == -1LL; - switch (CC) { - default: return SDValue(); - case ISD::SETEQ: { - // (zext (setcc %a, %b, seteq)) -> (lshr (cntlzw (xor %a, %b)), 5) - // (zext (setcc %a, 0, seteq)) -> (lshr (cntlzw %a), 5) - SDValue Xor = IsRHSZero ? LHS : - SDValue(CurDAG->getMachineNode(PPC::XOR, dl, MVT::i32, LHS, RHS), 0); - SDValue Clz = - SDValue(CurDAG->getMachineNode(PPC::CNTLZW, dl, MVT::i32, Xor), 0); - SDValue ShiftOps[] = { Clz, getI32Imm(27, dl), getI32Imm(5, dl), - getI32Imm(31, dl) }; - return SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32, - ShiftOps), 0); - } - case ISD::SETNE: { - // (zext (setcc %a, %b, setne)) -> (xor (lshr (cntlzw (xor %a, %b)), 5), 1) - // (zext (setcc %a, 0, setne)) -> (xor (lshr (cntlzw %a), 5), 1) - SDValue Xor = IsRHSZero ? LHS : - SDValue(CurDAG->getMachineNode(PPC::XOR, dl, MVT::i32, LHS, RHS), 0); - SDValue Clz = - SDValue(CurDAG->getMachineNode(PPC::CNTLZW, dl, MVT::i32, Xor), 0); - SDValue ShiftOps[] = { Clz, getI32Imm(27, dl), getI32Imm(5, dl), - getI32Imm(31, dl) }; - SDValue Shift = - SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32, ShiftOps), 0); - return SDValue(CurDAG->getMachineNode(PPC::XORI, dl, MVT::i32, Shift, - getI32Imm(1, dl)), 0); - } - case ISD::SETGE: { - // (zext (setcc %a, %b, setge)) -> (xor (lshr (sub %a, %b), 63), 1) - // (zext (setcc %a, 0, setge)) -> (lshr (~ %a), 31) - if(IsRHSZero) - return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt); - - // Not a special case (i.e. RHS == 0). Handle (%a >= %b) as (%b <= %a) - // by swapping inputs and falling through. - std::swap(LHS, RHS); - ConstantSDNode *RHSConst = dyn_cast<ConstantSDNode>(RHS); - IsRHSZero = RHSConst && RHSConst->isNullValue(); - LLVM_FALLTHROUGH; - } - case ISD::SETLE: { - // (zext (setcc %a, %b, setle)) -> (xor (lshr (sub %b, %a), 63), 1) - // (zext (setcc %a, 0, setle)) -> (xor (lshr (- %a), 63), 1) - if(IsRHSZero) - return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt); - - // The upper 32-bits of the register can't be undefined for this sequence. - LHS = signExtendInputIfNeeded(LHS); - RHS = signExtendInputIfNeeded(RHS); - SDValue Sub = - SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl, MVT::i64, LHS, RHS), 0); - SDValue Shift = - SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, Sub, - getI64Imm(1, dl), getI64Imm(63, dl)), 0); - return - SDValue(CurDAG->getMachineNode(PPC::XORI8, dl, - MVT::i64, Shift, getI32Imm(1, dl)), 0); - } - case ISD::SETGT: { - // (zext (setcc %a, %b, setgt)) -> (lshr (sub %b, %a), 63) - // (zext (setcc %a, -1, setgt)) -> (lshr (~ %a), 31) - // (zext (setcc %a, 0, setgt)) -> (lshr (- %a), 63) - // Handle SETLT -1 (which is equivalent to SETGE 0). - if (IsRHSNegOne) - return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt); - - if (IsRHSZero) { - // The upper 32-bits of the register can't be undefined for this sequence. - LHS = signExtendInputIfNeeded(LHS); - RHS = signExtendInputIfNeeded(RHS); - SDValue Neg = - SDValue(CurDAG->getMachineNode(PPC::NEG8, dl, MVT::i64, LHS), 0); - return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, - Neg, getI32Imm(1, dl), getI32Imm(63, dl)), 0); - } - // Not a special case (i.e. RHS == 0 or RHS == -1). Handle (%a > %b) as - // (%b < %a) by swapping inputs and falling through. - std::swap(LHS, RHS); - ConstantSDNode *RHSConst = dyn_cast<ConstantSDNode>(RHS); - IsRHSZero = RHSConst && RHSConst->isNullValue(); - IsRHSOne = RHSConst && RHSConst->getSExtValue() == 1; - LLVM_FALLTHROUGH; - } - case ISD::SETLT: { - // (zext (setcc %a, %b, setlt)) -> (lshr (sub %a, %b), 63) - // (zext (setcc %a, 1, setlt)) -> (xor (lshr (- %a), 63), 1) - // (zext (setcc %a, 0, setlt)) -> (lshr %a, 31) - // Handle SETLT 1 (which is equivalent to SETLE 0). - if (IsRHSOne) - return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt); - - if (IsRHSZero) { - SDValue ShiftOps[] = { LHS, getI32Imm(1, dl), getI32Imm(31, dl), - getI32Imm(31, dl) }; - return SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32, - ShiftOps), 0); - } - - // The upper 32-bits of the register can't be undefined for this sequence. - LHS = signExtendInputIfNeeded(LHS); - RHS = signExtendInputIfNeeded(RHS); - SDValue SUBFNode = - SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl, MVT::i64, RHS, LHS), 0); - return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, - SUBFNode, getI64Imm(1, dl), - getI64Imm(63, dl)), 0); - } - case ISD::SETUGE: - // (zext (setcc %a, %b, setuge)) -> (xor (lshr (sub %b, %a), 63), 1) - // (zext (setcc %a, %b, setule)) -> (xor (lshr (sub %a, %b), 63), 1) - std::swap(LHS, RHS); - LLVM_FALLTHROUGH; - case ISD::SETULE: { - // The upper 32-bits of the register can't be undefined for this sequence. - LHS = zeroExtendInputIfNeeded(LHS); - RHS = zeroExtendInputIfNeeded(RHS); - SDValue Subtract = - SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl, MVT::i64, LHS, RHS), 0); - SDValue SrdiNode = - SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, - Subtract, getI64Imm(1, dl), - getI64Imm(63, dl)), 0); - return SDValue(CurDAG->getMachineNode(PPC::XORI8, dl, MVT::i64, SrdiNode, - getI32Imm(1, dl)), 0); - } - case ISD::SETUGT: - // (zext (setcc %a, %b, setugt)) -> (lshr (sub %b, %a), 63) - // (zext (setcc %a, %b, setult)) -> (lshr (sub %a, %b), 63) - std::swap(LHS, RHS); - LLVM_FALLTHROUGH; - case ISD::SETULT: { - // The upper 32-bits of the register can't be undefined for this sequence. - LHS = zeroExtendInputIfNeeded(LHS); - RHS = zeroExtendInputIfNeeded(RHS); - SDValue Subtract = - SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl, MVT::i64, RHS, LHS), 0); - return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, - Subtract, getI64Imm(1, dl), - getI64Imm(63, dl)), 0); - } - } -} - -/// Produces a sign-extended result of comparing two 32-bit values according to -/// the passed condition code. -SDValue PPCDAGToDAGISel::get32BitSExtCompare(SDValue LHS, SDValue RHS, - ISD::CondCode CC, - int64_t RHSValue, SDLoc dl) { - bool IsRHSZero = RHSValue == 0; - bool IsRHSOne = RHSValue == 1; - bool IsRHSNegOne = RHSValue == -1LL; - - switch (CC) { - default: return SDValue(); - case ISD::SETEQ: { - // (sext (setcc %a, %b, seteq)) -> - // (ashr (shl (ctlz (xor %a, %b)), 58), 63) - // (sext (setcc %a, 0, seteq)) -> - // (ashr (shl (ctlz %a), 58), 63) - SDValue CountInput = IsRHSZero ? LHS : - SDValue(CurDAG->getMachineNode(PPC::XOR, dl, MVT::i32, LHS, RHS), 0); - SDValue Cntlzw = - SDValue(CurDAG->getMachineNode(PPC::CNTLZW, dl, MVT::i32, CountInput), 0); - SDValue SHLOps[] = { Cntlzw, getI32Imm(27, dl), - getI32Imm(5, dl), getI32Imm(31, dl) }; - SDValue Slwi = - SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32, SHLOps), 0); - return SDValue(CurDAG->getMachineNode(PPC::NEG, dl, MVT::i32, Slwi), 0); - } - case ISD::SETNE: { - // Bitwise xor the operands, count leading zeros, shift right by 5 bits and - // flip the bit, finally take 2's complement. - // (sext (setcc %a, %b, setne)) -> - // (neg (xor (lshr (ctlz (xor %a, %b)), 5), 1)) - // Same as above, but the first xor is not needed. - // (sext (setcc %a, 0, setne)) -> - // (neg (xor (lshr (ctlz %a), 5), 1)) - SDValue Xor = IsRHSZero ? LHS : - SDValue(CurDAG->getMachineNode(PPC::XOR, dl, MVT::i32, LHS, RHS), 0); - SDValue Clz = - SDValue(CurDAG->getMachineNode(PPC::CNTLZW, dl, MVT::i32, Xor), 0); - SDValue ShiftOps[] = - { Clz, getI32Imm(27, dl), getI32Imm(5, dl), getI32Imm(31, dl) }; - SDValue Shift = - SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32, ShiftOps), 0); - SDValue Xori = - SDValue(CurDAG->getMachineNode(PPC::XORI, dl, MVT::i32, Shift, - getI32Imm(1, dl)), 0); - return SDValue(CurDAG->getMachineNode(PPC::NEG, dl, MVT::i32, Xori), 0); - } - case ISD::SETGE: { - // (sext (setcc %a, %b, setge)) -> (add (lshr (sub %a, %b), 63), -1) - // (sext (setcc %a, 0, setge)) -> (ashr (~ %a), 31) - if (IsRHSZero) - return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt); - - // Not a special case (i.e. RHS == 0). Handle (%a >= %b) as (%b <= %a) - // by swapping inputs and falling through. - std::swap(LHS, RHS); - ConstantSDNode *RHSConst = dyn_cast<ConstantSDNode>(RHS); - IsRHSZero = RHSConst && RHSConst->isNullValue(); - LLVM_FALLTHROUGH; - } - case ISD::SETLE: { - // (sext (setcc %a, %b, setge)) -> (add (lshr (sub %b, %a), 63), -1) - // (sext (setcc %a, 0, setle)) -> (add (lshr (- %a), 63), -1) - if (IsRHSZero) - return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt); - - // The upper 32-bits of the register can't be undefined for this sequence. - LHS = signExtendInputIfNeeded(LHS); - RHS = signExtendInputIfNeeded(RHS); - SDValue SUBFNode = - SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl, MVT::i64, MVT::Glue, - LHS, RHS), 0); - SDValue Srdi = - SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, - SUBFNode, getI64Imm(1, dl), - getI64Imm(63, dl)), 0); - return SDValue(CurDAG->getMachineNode(PPC::ADDI8, dl, MVT::i64, Srdi, - getI32Imm(-1, dl)), 0); - } - case ISD::SETGT: { - // (sext (setcc %a, %b, setgt)) -> (ashr (sub %b, %a), 63) - // (sext (setcc %a, -1, setgt)) -> (ashr (~ %a), 31) - // (sext (setcc %a, 0, setgt)) -> (ashr (- %a), 63) - if (IsRHSNegOne) - return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt); - if (IsRHSZero) { - // The upper 32-bits of the register can't be undefined for this sequence. - LHS = signExtendInputIfNeeded(LHS); - RHS = signExtendInputIfNeeded(RHS); - SDValue Neg = - SDValue(CurDAG->getMachineNode(PPC::NEG8, dl, MVT::i64, LHS), 0); - return SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64, Neg, - getI64Imm(63, dl)), 0); - } - // Not a special case (i.e. RHS == 0 or RHS == -1). Handle (%a > %b) as - // (%b < %a) by swapping inputs and falling through. - std::swap(LHS, RHS); - ConstantSDNode *RHSConst = dyn_cast<ConstantSDNode>(RHS); - IsRHSZero = RHSConst && RHSConst->isNullValue(); - IsRHSOne = RHSConst && RHSConst->getSExtValue() == 1; - LLVM_FALLTHROUGH; - } - case ISD::SETLT: { - // (sext (setcc %a, %b, setgt)) -> (ashr (sub %a, %b), 63) - // (sext (setcc %a, 1, setgt)) -> (add (lshr (- %a), 63), -1) - // (sext (setcc %a, 0, setgt)) -> (ashr %a, 31) - if (IsRHSOne) - return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt); - if (IsRHSZero) - return SDValue(CurDAG->getMachineNode(PPC::SRAWI, dl, MVT::i32, LHS, - getI32Imm(31, dl)), 0); - - // The upper 32-bits of the register can't be undefined for this sequence. - LHS = signExtendInputIfNeeded(LHS); - RHS = signExtendInputIfNeeded(RHS); - SDValue SUBFNode = - SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl, MVT::i64, RHS, LHS), 0); - return SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64, - SUBFNode, getI64Imm(63, dl)), 0); - } - case ISD::SETUGE: - // (sext (setcc %a, %b, setuge)) -> (add (lshr (sub %a, %b), 63), -1) - // (sext (setcc %a, %b, setule)) -> (add (lshr (sub %b, %a), 63), -1) - std::swap(LHS, RHS); - LLVM_FALLTHROUGH; - case ISD::SETULE: { - // The upper 32-bits of the register can't be undefined for this sequence. - LHS = zeroExtendInputIfNeeded(LHS); - RHS = zeroExtendInputIfNeeded(RHS); - SDValue Subtract = - SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl, MVT::i64, LHS, RHS), 0); - SDValue Shift = - SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, Subtract, - getI32Imm(1, dl), getI32Imm(63,dl)), 0); - return SDValue(CurDAG->getMachineNode(PPC::ADDI8, dl, MVT::i64, Shift, - getI32Imm(-1, dl)), 0); - } - case ISD::SETUGT: - // (sext (setcc %a, %b, setugt)) -> (ashr (sub %b, %a), 63) - // (sext (setcc %a, %b, setugt)) -> (ashr (sub %a, %b), 63) - std::swap(LHS, RHS); - LLVM_FALLTHROUGH; - case ISD::SETULT: { - // The upper 32-bits of the register can't be undefined for this sequence. - LHS = zeroExtendInputIfNeeded(LHS); - RHS = zeroExtendInputIfNeeded(RHS); - SDValue Subtract = - SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl, MVT::i64, RHS, LHS), 0); - return SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64, - Subtract, getI64Imm(63, dl)), 0); - } - } -} - -/// Produces a zero-extended result of comparing two 64-bit values according to -/// the passed condition code. -SDValue PPCDAGToDAGISel::get64BitZExtCompare(SDValue LHS, SDValue RHS, - ISD::CondCode CC, - int64_t RHSValue, SDLoc dl) { - bool IsRHSZero = RHSValue == 0; - bool IsRHSOne = RHSValue == 1; - bool IsRHSNegOne = RHSValue == -1LL; - switch (CC) { - default: return SDValue(); - case ISD::SETEQ: { - // (zext (setcc %a, %b, seteq)) -> (lshr (ctlz (xor %a, %b)), 6) - // (zext (setcc %a, 0, seteq)) -> (lshr (ctlz %a), 6) - SDValue Xor = IsRHSZero ? LHS : - SDValue(CurDAG->getMachineNode(PPC::XOR8, dl, MVT::i64, LHS, RHS), 0); - SDValue Clz = - SDValue(CurDAG->getMachineNode(PPC::CNTLZD, dl, MVT::i64, Xor), 0); - return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, Clz, - getI64Imm(58, dl), getI64Imm(63, dl)), - 0); - } - case ISD::SETNE: { - // {addc.reg, addc.CA} = (addcarry (xor %a, %b), -1) - // (zext (setcc %a, %b, setne)) -> (sube addc.reg, addc.reg, addc.CA) - // {addcz.reg, addcz.CA} = (addcarry %a, -1) - // (zext (setcc %a, 0, setne)) -> (sube addcz.reg, addcz.reg, addcz.CA) - SDValue Xor = IsRHSZero ? LHS : - SDValue(CurDAG->getMachineNode(PPC::XOR8, dl, MVT::i64, LHS, RHS), 0); - SDValue AC = - SDValue(CurDAG->getMachineNode(PPC::ADDIC8, dl, MVT::i64, MVT::Glue, - Xor, getI32Imm(~0U, dl)), 0); - return SDValue(CurDAG->getMachineNode(PPC::SUBFE8, dl, MVT::i64, AC, - Xor, AC.getValue(1)), 0); - } - case ISD::SETGE: { - // {subc.reg, subc.CA} = (subcarry %a, %b) - // (zext (setcc %a, %b, setge)) -> - // (adde (lshr %b, 63), (ashr %a, 63), subc.CA) - // (zext (setcc %a, 0, setge)) -> (lshr (~ %a), 63) - if (IsRHSZero) - return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt); - std::swap(LHS, RHS); - ConstantSDNode *RHSConst = dyn_cast<ConstantSDNode>(RHS); - IsRHSZero = RHSConst && RHSConst->isNullValue(); - LLVM_FALLTHROUGH; - } - case ISD::SETLE: { - // {subc.reg, subc.CA} = (subcarry %b, %a) - // (zext (setcc %a, %b, setge)) -> - // (adde (lshr %a, 63), (ashr %b, 63), subc.CA) - // (zext (setcc %a, 0, setge)) -> (lshr (or %a, (add %a, -1)), 63) - if (IsRHSZero) - return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt); - SDValue ShiftL = - SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, LHS, - getI64Imm(1, dl), getI64Imm(63, dl)), 0); - SDValue ShiftR = - SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64, RHS, - getI64Imm(63, dl)), 0); - SDValue SubtractCarry = - SDValue(CurDAG->getMachineNode(PPC::SUBFC8, dl, MVT::i64, MVT::Glue, - LHS, RHS), 1); - return SDValue(CurDAG->getMachineNode(PPC::ADDE8, dl, MVT::i64, MVT::Glue, - ShiftR, ShiftL, SubtractCarry), 0); - } - case ISD::SETGT: { - // {subc.reg, subc.CA} = (subcarry %b, %a) - // (zext (setcc %a, %b, setgt)) -> - // (xor (adde (lshr %a, 63), (ashr %b, 63), subc.CA), 1) - // (zext (setcc %a, 0, setgt)) -> (lshr (nor (add %a, -1), %a), 63) - if (IsRHSNegOne) - return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt); - if (IsRHSZero) { - SDValue Addi = - SDValue(CurDAG->getMachineNode(PPC::ADDI8, dl, MVT::i64, LHS, - getI64Imm(~0ULL, dl)), 0); - SDValue Nor = - SDValue(CurDAG->getMachineNode(PPC::NOR8, dl, MVT::i64, Addi, LHS), 0); - return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, Nor, - getI64Imm(1, dl), - getI64Imm(63, dl)), 0); - } - std::swap(LHS, RHS); - ConstantSDNode *RHSConst = dyn_cast<ConstantSDNode>(RHS); - IsRHSZero = RHSConst && RHSConst->isNullValue(); - IsRHSOne = RHSConst && RHSConst->getSExtValue() == 1; - LLVM_FALLTHROUGH; - } - case ISD::SETLT: { - // {subc.reg, subc.CA} = (subcarry %a, %b) - // (zext (setcc %a, %b, setlt)) -> - // (xor (adde (lshr %b, 63), (ashr %a, 63), subc.CA), 1) - // (zext (setcc %a, 0, setlt)) -> (lshr %a, 63) - if (IsRHSOne) - return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt); - if (IsRHSZero) - return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, LHS, - getI64Imm(1, dl), - getI64Imm(63, dl)), 0); - SDValue SRADINode = - SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64, - LHS, getI64Imm(63, dl)), 0); - SDValue SRDINode = - SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, - RHS, getI64Imm(1, dl), - getI64Imm(63, dl)), 0); - SDValue SUBFC8Carry = - SDValue(CurDAG->getMachineNode(PPC::SUBFC8, dl, MVT::i64, MVT::Glue, - RHS, LHS), 1); - SDValue ADDE8Node = - SDValue(CurDAG->getMachineNode(PPC::ADDE8, dl, MVT::i64, MVT::Glue, - SRDINode, SRADINode, SUBFC8Carry), 0); - return SDValue(CurDAG->getMachineNode(PPC::XORI8, dl, MVT::i64, - ADDE8Node, getI64Imm(1, dl)), 0); - } - } -} - -/// Produces a sign-extended result of comparing two 64-bit values according to -/// the passed condition code. -SDValue PPCDAGToDAGISel::get64BitSExtCompare(SDValue LHS, SDValue RHS, - ISD::CondCode CC, - int64_t RHSValue, SDLoc dl) { - bool IsRHSZero = RHSValue == 0; - bool IsRHSOne = RHSValue == 1; - bool IsRHSNegOne = RHSValue == -1LL; - switch (CC) { - default: return SDValue(); - case ISD::SETEQ: { - // {addc.reg, addc.CA} = (addcarry (xor %a, %b), -1) - // (sext (setcc %a, %b, seteq)) -> (sube addc.reg, addc.reg, addc.CA) - // {addcz.reg, addcz.CA} = (addcarry %a, -1) - // (sext (setcc %a, 0, seteq)) -> (sube addcz.reg, addcz.reg, addcz.CA) - SDValue AddInput = IsRHSZero ? LHS : - SDValue(CurDAG->getMachineNode(PPC::XOR8, dl, MVT::i64, LHS, RHS), 0); - SDValue Addic = - SDValue(CurDAG->getMachineNode(PPC::ADDIC8, dl, MVT::i64, MVT::Glue, - AddInput, getI32Imm(~0U, dl)), 0); - return SDValue(CurDAG->getMachineNode(PPC::SUBFE8, dl, MVT::i64, Addic, - Addic, Addic.getValue(1)), 0); - } - case ISD::SETNE: { - // {subfc.reg, subfc.CA} = (subcarry 0, (xor %a, %b)) - // (sext (setcc %a, %b, setne)) -> (sube subfc.reg, subfc.reg, subfc.CA) - // {subfcz.reg, subfcz.CA} = (subcarry 0, %a) - // (sext (setcc %a, 0, setne)) -> (sube subfcz.reg, subfcz.reg, subfcz.CA) - SDValue Xor = IsRHSZero ? LHS : - SDValue(CurDAG->getMachineNode(PPC::XOR8, dl, MVT::i64, LHS, RHS), 0); - SDValue SC = - SDValue(CurDAG->getMachineNode(PPC::SUBFIC8, dl, MVT::i64, MVT::Glue, - Xor, getI32Imm(0, dl)), 0); - return SDValue(CurDAG->getMachineNode(PPC::SUBFE8, dl, MVT::i64, SC, - SC, SC.getValue(1)), 0); - } - case ISD::SETGE: { - // {subc.reg, subc.CA} = (subcarry %a, %b) - // (zext (setcc %a, %b, setge)) -> - // (- (adde (lshr %b, 63), (ashr %a, 63), subc.CA)) - // (zext (setcc %a, 0, setge)) -> (~ (ashr %a, 63)) - if (IsRHSZero) - return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt); - std::swap(LHS, RHS); - ConstantSDNode *RHSConst = dyn_cast<ConstantSDNode>(RHS); - IsRHSZero = RHSConst && RHSConst->isNullValue(); - LLVM_FALLTHROUGH; - } - case ISD::SETLE: { - // {subc.reg, subc.CA} = (subcarry %b, %a) - // (zext (setcc %a, %b, setge)) -> - // (- (adde (lshr %a, 63), (ashr %b, 63), subc.CA)) - // (zext (setcc %a, 0, setge)) -> (ashr (or %a, (add %a, -1)), 63) - if (IsRHSZero) - return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt); - SDValue ShiftR = - SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64, RHS, - getI64Imm(63, dl)), 0); - SDValue ShiftL = - SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, LHS, - getI64Imm(1, dl), getI64Imm(63, dl)), 0); - SDValue SubtractCarry = - SDValue(CurDAG->getMachineNode(PPC::SUBFC8, dl, MVT::i64, MVT::Glue, - LHS, RHS), 1); - SDValue Adde = - SDValue(CurDAG->getMachineNode(PPC::ADDE8, dl, MVT::i64, MVT::Glue, - ShiftR, ShiftL, SubtractCarry), 0); - return SDValue(CurDAG->getMachineNode(PPC::NEG8, dl, MVT::i64, Adde), 0); - } - case ISD::SETGT: { - // {subc.reg, subc.CA} = (subcarry %b, %a) - // (zext (setcc %a, %b, setgt)) -> - // -(xor (adde (lshr %a, 63), (ashr %b, 63), subc.CA), 1) - // (zext (setcc %a, 0, setgt)) -> (ashr (nor (add %a, -1), %a), 63) - if (IsRHSNegOne) - return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt); - if (IsRHSZero) { - SDValue Add = - SDValue(CurDAG->getMachineNode(PPC::ADDI8, dl, MVT::i64, LHS, - getI64Imm(-1, dl)), 0); - SDValue Nor = - SDValue(CurDAG->getMachineNode(PPC::NOR8, dl, MVT::i64, Add, LHS), 0); - return SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64, Nor, - getI64Imm(63, dl)), 0); - } - std::swap(LHS, RHS); - ConstantSDNode *RHSConst = dyn_cast<ConstantSDNode>(RHS); - IsRHSZero = RHSConst && RHSConst->isNullValue(); - IsRHSOne = RHSConst && RHSConst->getSExtValue() == 1; - LLVM_FALLTHROUGH; - } - case ISD::SETLT: { - // {subc.reg, subc.CA} = (subcarry %a, %b) - // (zext (setcc %a, %b, setlt)) -> - // -(xor (adde (lshr %b, 63), (ashr %a, 63), subc.CA), 1) - // (zext (setcc %a, 0, setlt)) -> (ashr %a, 63) - if (IsRHSOne) - return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt); - if (IsRHSZero) { - return SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64, LHS, - getI64Imm(63, dl)), 0); - } - SDValue SRADINode = - SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64, - LHS, getI64Imm(63, dl)), 0); - SDValue SRDINode = - SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, - RHS, getI64Imm(1, dl), - getI64Imm(63, dl)), 0); - SDValue SUBFC8Carry = - SDValue(CurDAG->getMachineNode(PPC::SUBFC8, dl, MVT::i64, MVT::Glue, - RHS, LHS), 1); - SDValue ADDE8Node = - SDValue(CurDAG->getMachineNode(PPC::ADDE8, dl, MVT::i64, - SRDINode, SRADINode, SUBFC8Carry), 0); - SDValue XORI8Node = - SDValue(CurDAG->getMachineNode(PPC::XORI8, dl, MVT::i64, - ADDE8Node, getI64Imm(1, dl)), 0); - return SDValue(CurDAG->getMachineNode(PPC::NEG8, dl, MVT::i64, - XORI8Node), 0); - } - } -} - -/// Does this SDValue have any uses for which keeping the value in a GPR is -/// appropriate. This is meant to be used on values that have type i1 since -/// it is somewhat meaningless to ask if values of other types can be kept in -/// GPR's. -static bool allUsesExtend(SDValue Compare, SelectionDAG *CurDAG) { - assert(Compare.getOpcode() == ISD::SETCC && - "An ISD::SETCC node required here."); - - // For values that have a single use, the caller should obviously already have - // checked if that use is an extending use. We check the other uses here. - if (Compare.hasOneUse()) - return true; - // We want the value in a GPR if it is being extended, used for a select, or - // used in logical operations. - for (auto CompareUse : Compare.getNode()->uses()) - if (CompareUse->getOpcode() != ISD::SIGN_EXTEND && - CompareUse->getOpcode() != ISD::ZERO_EXTEND && - CompareUse->getOpcode() != ISD::SELECT && - !isLogicOp(CompareUse->getOpcode())) { - OmittedForNonExtendUses++; - return false; - } - return true; -} - -/// Returns an equivalent of a SETCC node but with the result the same width as -/// the inputs. This can nalso be used for SELECT_CC if either the true or false -/// values is a power of two while the other is zero. -SDValue PPCDAGToDAGISel::getSETCCInGPR(SDValue Compare, - SetccInGPROpts ConvOpts) { - assert((Compare.getOpcode() == ISD::SETCC || - Compare.getOpcode() == ISD::SELECT_CC) && - "An ISD::SETCC node required here."); - - // Don't convert this comparison to a GPR sequence because there are uses - // of the i1 result (i.e. uses that require the result in the CR). - if ((Compare.getOpcode() == ISD::SETCC) && !allUsesExtend(Compare, CurDAG)) - return SDValue(); - - SDValue LHS = Compare.getOperand(0); - SDValue RHS = Compare.getOperand(1); - - // The condition code is operand 2 for SETCC and operand 4 for SELECT_CC. - int CCOpNum = Compare.getOpcode() == ISD::SELECT_CC ? 4 : 2; - ISD::CondCode CC = - cast<CondCodeSDNode>(Compare.getOperand(CCOpNum))->get(); - EVT InputVT = LHS.getValueType(); - if (InputVT != MVT::i32 && InputVT != MVT::i64) - return SDValue(); - - if (ConvOpts == SetccInGPROpts::ZExtInvert || - ConvOpts == SetccInGPROpts::SExtInvert) - CC = ISD::getSetCCInverse(CC, true); - - bool Inputs32Bit = InputVT == MVT::i32; - - SDLoc dl(Compare); - ConstantSDNode *RHSConst = dyn_cast<ConstantSDNode>(RHS); - int64_t RHSValue = RHSConst ? RHSConst->getSExtValue() : INT64_MAX; - bool IsSext = ConvOpts == SetccInGPROpts::SExtOrig || - ConvOpts == SetccInGPROpts::SExtInvert; - - if (IsSext && Inputs32Bit) - return get32BitSExtCompare(LHS, RHS, CC, RHSValue, dl); - else if (Inputs32Bit) - return get32BitZExtCompare(LHS, RHS, CC, RHSValue, dl); - else if (IsSext) - return get64BitSExtCompare(LHS, RHS, CC, RHSValue, dl); - return get64BitZExtCompare(LHS, RHS, CC, RHSValue, dl); -} - /// Does this node represent a load/store node whose address can be represented /// with a register plus an immediate that's a multiple of \p Val: bool PPCDAGToDAGISel::isOffsetMultipleOf(SDNode *N, unsigned Val) const { @@ -3589,12 +2543,6 @@ void PPCDAGToDAGISel::Select(SDNode *N) { } break; - case ISD::ZERO_EXTEND: - case ISD::SIGN_EXTEND: - if (tryEXTEND(N)) - return; - break; - case ISD::SETCC: if (trySETCC(N)) return; @@ -3738,9 +2686,6 @@ void PPCDAGToDAGISel::Select(SDNode *N) { } case ISD::AND: { - if (tryLogicOpOfCompares(N)) - return; - unsigned Imm, Imm2, SH, MB, ME; uint64_t Imm64; @@ -3860,9 +2805,6 @@ void PPCDAGToDAGISel::Select(SDNode *N) { if (tryBitfieldInsert(N)) return; - if (tryLogicOpOfCompares(N)) - return; - int16_t Imm; if (N->getOperand(0)->getOpcode() == ISD::FrameIndex && isIntS16Immediate(N->getOperand(1), Imm)) { @@ -3900,9 +2842,6 @@ void PPCDAGToDAGISel::Select(SDNode *N) { break; } case ISD::XOR: { - if (tryLogicOpOfCompares(N)) - return; - // XOR with a 32-bit immediate can be handled by xori + xoris // without creating an immediate in a GPR. uint64_t Imm64 = 0; |