diff options
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp')
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 401 |
1 files changed, 231 insertions, 170 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 4ad6c88233fe..776ec52e2604 100644 --- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -138,9 +138,9 @@ namespace { /// class PPCDAGToDAGISel : public SelectionDAGISel { const PPCTargetMachine &TM; - const PPCSubtarget *PPCSubTarget; - const PPCTargetLowering *PPCLowering; - unsigned GlobalBaseReg; + const PPCSubtarget *PPCSubTarget = nullptr; + const PPCTargetLowering *PPCLowering = nullptr; + unsigned GlobalBaseReg = 0; public: explicit PPCDAGToDAGISel(PPCTargetMachine &tm, CodeGenOpt::Level OptLevel) @@ -204,6 +204,7 @@ namespace { bool tryBitfieldInsert(SDNode *N); bool tryBitPermutation(SDNode *N); bool tryIntCompareInGPR(SDNode *N); + bool tryAndWithMask(SDNode *N); // tryTLSXFormLoad - Convert an ISD::LOAD fed by a PPCISD::ADD_TLS into // an X-Form load instruction with the offset being a relocation coming from @@ -309,7 +310,6 @@ namespace { errs() << "ConstraintID: " << ConstraintID << "\n"; llvm_unreachable("Unexpected asm memory constraint"); case InlineAsm::Constraint_es: - case InlineAsm::Constraint_i: case InlineAsm::Constraint_m: case InlineAsm::Constraint_o: case InlineAsm::Constraint_Q: @@ -512,13 +512,14 @@ static bool isInt64Immediate(SDValue N, uint64_t &Imm) { return isInt64Immediate(N.getNode(), Imm); } -static unsigned getBranchHint(unsigned PCC, FunctionLoweringInfo *FuncInfo, +static unsigned getBranchHint(unsigned PCC, + const FunctionLoweringInfo &FuncInfo, const SDValue &DestMBB) { assert(isa<BasicBlockSDNode>(DestMBB)); - if (!FuncInfo->BPI) return PPC::BR_NO_HINT; + if (!FuncInfo.BPI) return PPC::BR_NO_HINT; - const BasicBlock *BB = FuncInfo->MBB->getBasicBlock(); + const BasicBlock *BB = FuncInfo.MBB->getBasicBlock(); const Instruction *BBTerm = BB->getTerminator(); if (BBTerm->getNumSuccessors() != 2) return PPC::BR_NO_HINT; @@ -526,8 +527,8 @@ static unsigned getBranchHint(unsigned PCC, FunctionLoweringInfo *FuncInfo, const BasicBlock *TBB = BBTerm->getSuccessor(0); const BasicBlock *FBB = BBTerm->getSuccessor(1); - auto TProb = FuncInfo->BPI->getEdgeProbability(BB, TBB); - auto FProb = FuncInfo->BPI->getEdgeProbability(BB, FBB); + auto TProb = FuncInfo.BPI->getEdgeProbability(BB, TBB); + auto FProb = FuncInfo.BPI->getEdgeProbability(BB, FBB); // We only want to handle cases which are easy to predict at static time, e.g. // C++ throw statement, that is very likely not taken, or calling never @@ -547,7 +548,7 @@ static unsigned getBranchHint(unsigned PCC, FunctionLoweringInfo *FuncInfo, if (std::max(TProb, FProb) / Threshold < std::min(TProb, FProb)) return PPC::BR_NO_HINT; - LLVM_DEBUG(dbgs() << "Use branch hint for '" << FuncInfo->Fn->getName() + LLVM_DEBUG(dbgs() << "Use branch hint for '" << FuncInfo.Fn->getName() << "::" << BB->getName() << "'\n" << " -> " << TBB->getName() << ": " << TProb << "\n" << " -> " << FBB->getName() << ": " << FProb << "\n"); @@ -1044,7 +1045,7 @@ static unsigned allUsesTruncate(SelectionDAG *CurDAG, SDNode *N) { if (Use->isMachineOpcode()) return 0; MaxTruncation = - std::max(MaxTruncation, Use->getValueType(0).getSizeInBits()); + std::max(MaxTruncation, (unsigned)Use->getValueType(0).getSizeInBits()); continue; case ISD::STORE: { if (Use->isMachineOpcode()) @@ -1399,11 +1400,14 @@ class BitPermutationSelector { for (unsigned i = 0; i < NumValidBits; ++i) Bits[i] = (*LHSBits)[i]; - // These bits are known to be zero. + // These bits are known to be zero but the AssertZext may be from a value + // that already has some constant zero bits (i.e. from a masking and). for (unsigned i = NumValidBits; i < NumBits; ++i) - Bits[i] = ValueBit((*LHSBits)[i].getValue(), - (*LHSBits)[i].getValueBitIndex(), - ValueBit::VariableKnownToBeZero); + Bits[i] = (*LHSBits)[i].hasValue() + ? ValueBit((*LHSBits)[i].getValue(), + (*LHSBits)[i].getValueBitIndex(), + ValueBit::VariableKnownToBeZero) + : ValueBit(ValueBit::ConstZero); return std::make_pair(Interesting, &Bits); } @@ -1811,11 +1815,14 @@ class BitPermutationSelector { SDValue ANDIVal, ANDISVal; if (ANDIMask != 0) - ANDIVal = SDValue(CurDAG->getMachineNode(PPC::ANDIo, dl, MVT::i32, - VRot, getI32Imm(ANDIMask, dl)), 0); + ANDIVal = SDValue(CurDAG->getMachineNode(PPC::ANDI_rec, dl, MVT::i32, + VRot, getI32Imm(ANDIMask, dl)), + 0); if (ANDISMask != 0) - ANDISVal = SDValue(CurDAG->getMachineNode(PPC::ANDISo, dl, MVT::i32, - VRot, getI32Imm(ANDISMask, dl)), 0); + ANDISVal = + SDValue(CurDAG->getMachineNode(PPC::ANDIS_rec, dl, MVT::i32, VRot, + getI32Imm(ANDISMask, dl)), + 0); SDValue TotalVal; if (!ANDIVal) @@ -1904,11 +1911,14 @@ class BitPermutationSelector { SDValue ANDIVal, ANDISVal; if (ANDIMask != 0) - ANDIVal = SDValue(CurDAG->getMachineNode(PPC::ANDIo, dl, MVT::i32, - Res, getI32Imm(ANDIMask, dl)), 0); + ANDIVal = SDValue(CurDAG->getMachineNode(PPC::ANDI_rec, dl, MVT::i32, + Res, getI32Imm(ANDIMask, dl)), + 0); if (ANDISMask != 0) - ANDISVal = SDValue(CurDAG->getMachineNode(PPC::ANDISo, dl, MVT::i32, - Res, getI32Imm(ANDISMask, dl)), 0); + ANDISVal = + SDValue(CurDAG->getMachineNode(PPC::ANDIS_rec, dl, MVT::i32, Res, + getI32Imm(ANDISMask, dl)), + 0); if (!ANDIVal) Res = ANDISVal; @@ -2181,15 +2191,16 @@ class BitPermutationSelector { SDValue ANDIVal, ANDISVal; if (ANDIMask != 0) - ANDIVal = SDValue(CurDAG->getMachineNode(PPC::ANDIo8, dl, MVT::i64, + ANDIVal = SDValue(CurDAG->getMachineNode(PPC::ANDI8_rec, dl, MVT::i64, ExtendToInt64(VRot, dl), getI32Imm(ANDIMask, dl)), 0); if (ANDISMask != 0) - ANDISVal = SDValue(CurDAG->getMachineNode(PPC::ANDISo8, dl, MVT::i64, - ExtendToInt64(VRot, dl), - getI32Imm(ANDISMask, dl)), - 0); + ANDISVal = + SDValue(CurDAG->getMachineNode(PPC::ANDIS8_rec, dl, MVT::i64, + ExtendToInt64(VRot, dl), + getI32Imm(ANDISMask, dl)), + 0); if (!ANDIVal) TotalVal = ANDISVal; @@ -2330,11 +2341,16 @@ class BitPermutationSelector { SDValue ANDIVal, ANDISVal; if (ANDIMask != 0) - ANDIVal = SDValue(CurDAG->getMachineNode(PPC::ANDIo8, dl, MVT::i64, - ExtendToInt64(Res, dl), getI32Imm(ANDIMask, dl)), 0); + ANDIVal = SDValue(CurDAG->getMachineNode(PPC::ANDI8_rec, dl, MVT::i64, + ExtendToInt64(Res, dl), + getI32Imm(ANDIMask, dl)), + 0); if (ANDISMask != 0) - ANDISVal = SDValue(CurDAG->getMachineNode(PPC::ANDISo8, dl, MVT::i64, - ExtendToInt64(Res, dl), getI32Imm(ANDISMask, dl)), 0); + ANDISVal = + SDValue(CurDAG->getMachineNode(PPC::ANDIS8_rec, dl, MVT::i64, + ExtendToInt64(Res, dl), + getI32Imm(ANDISMask, dl)), + 0); if (!ANDIVal) Res = ANDISVal; @@ -2385,7 +2401,7 @@ class BitPermutationSelector { SmallVector<ValueBit, 64> Bits; - bool NeedMask; + bool NeedMask = false; SmallVector<unsigned, 64> RLAmt; SmallVector<BitGroup, 16> BitGroups; @@ -2393,7 +2409,7 @@ class BitPermutationSelector { DenseMap<std::pair<SDValue, unsigned>, ValueRotInfo> ValueRots; SmallVector<ValueRotInfo, 16> ValueRotsVec; - SelectionDAG *CurDAG; + SelectionDAG *CurDAG = nullptr; public: BitPermutationSelector(SelectionDAG *DAG) @@ -2623,8 +2639,9 @@ SDNode *IntegerCompareEliminator::tryLogicOpOfCompares(SDNode *N) { 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); + SDValue(CurDAG->getMachineNode(NewOpc == -1 ? PPC::ANDI8_rec : NewOpc, + dl, MVT::i64, MVT::Glue, LHS, RHS), + 0); } // Select this node to a single bit from CR0 set by the record-form node @@ -3597,7 +3614,7 @@ SDValue IntegerCompareEliminator::getSETCCInGPR(SDValue Compare, if (ConvOpts == SetccInGPROpts::ZExtInvert || ConvOpts == SetccInGPROpts::SExtInvert) - CC = ISD::getSetCCInverse(CC, true); + CC = ISD::getSetCCInverse(CC, InputVT); bool Inputs32Bit = InputVT == MVT::i32; @@ -3832,7 +3849,11 @@ SDValue PPCDAGToDAGISel::SelectCC(SDValue LHS, SDValue RHS, ISD::CondCode CC, return SDValue(CurDAG->getMachineNode(Opc, dl, MVT::i32, LHS, RHS), 0); } -static PPC::Predicate getPredicateForSetCC(ISD::CondCode CC) { +static PPC::Predicate getPredicateForSetCC(ISD::CondCode CC, const EVT &VT, + const PPCSubtarget *Subtarget) { + // For SPE instructions, the result is in GT bit of the CR + bool UseSPE = Subtarget->hasSPE() && VT.isFloatingPoint(); + switch (CC) { case ISD::SETUEQ: case ISD::SETONE: @@ -3841,17 +3862,23 @@ static PPC::Predicate getPredicateForSetCC(ISD::CondCode CC) { llvm_unreachable("Should be lowered by legalize!"); default: llvm_unreachable("Unknown condition!"); case ISD::SETOEQ: - case ISD::SETEQ: return PPC::PRED_EQ; + case ISD::SETEQ: + return UseSPE ? PPC::PRED_GT : PPC::PRED_EQ; case ISD::SETUNE: - case ISD::SETNE: return PPC::PRED_NE; + case ISD::SETNE: + return UseSPE ? PPC::PRED_LE : PPC::PRED_NE; case ISD::SETOLT: - case ISD::SETLT: return PPC::PRED_LT; + case ISD::SETLT: + return UseSPE ? PPC::PRED_GT : PPC::PRED_LT; case ISD::SETULE: - case ISD::SETLE: return PPC::PRED_LE; + case ISD::SETLE: + return UseSPE ? PPC::PRED_LE : PPC::PRED_LE; case ISD::SETOGT: - case ISD::SETGT: return PPC::PRED_GT; + case ISD::SETGT: + return UseSPE ? PPC::PRED_GT : PPC::PRED_GT; case ISD::SETUGE: - case ISD::SETGE: return PPC::PRED_GE; + case ISD::SETGE: + return UseSPE ? PPC::PRED_LE : PPC::PRED_GE; case ISD::SETO: return PPC::PRED_NU; case ISD::SETUO: return PPC::PRED_UN; // These two are invalid for floating point. Assume we have int. @@ -4344,6 +4371,142 @@ static bool mayUseP9Setb(SDNode *N, const ISD::CondCode &CC, SelectionDAG *DAG, return true; } +bool PPCDAGToDAGISel::tryAndWithMask(SDNode *N) { + if (N->getOpcode() != ISD::AND) + return false; + + SDLoc dl(N); + SDValue Val = N->getOperand(0); + unsigned Imm, Imm2, SH, MB, ME; + uint64_t Imm64; + + // If this is an and of a value rotated between 0 and 31 bits and then and'd + // with a mask, emit rlwinm + if (isInt32Immediate(N->getOperand(1), Imm) && + isRotateAndMask(N->getOperand(0).getNode(), Imm, false, SH, MB, ME)) { + SDValue Val = N->getOperand(0).getOperand(0); + SDValue Ops[] = { Val, getI32Imm(SH, dl), getI32Imm(MB, dl), + getI32Imm(ME, dl) }; + CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Ops); + return true; + } + + // If this is just a masked value where the input is not handled, and + // is not a rotate-left (handled by a pattern in the .td file), emit rlwinm + if (isInt32Immediate(N->getOperand(1), Imm)) { + if (isRunOfOnes(Imm, MB, ME) && + N->getOperand(0).getOpcode() != ISD::ROTL) { + SDValue Ops[] = { Val, getI32Imm(0, dl), getI32Imm(MB, dl), + getI32Imm(ME, dl) }; + CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Ops); + return true; + } + // AND X, 0 -> 0, not "rlwinm 32". + if (Imm == 0) { + ReplaceUses(SDValue(N, 0), N->getOperand(1)); + return true; + } + + // ISD::OR doesn't get all the bitfield insertion fun. + // (and (or x, c1), c2) where isRunOfOnes(~(c1^c2)) might be a + // bitfield insert. + if (N->getOperand(0).getOpcode() == ISD::OR && + isInt32Immediate(N->getOperand(0).getOperand(1), Imm2)) { + // The idea here is to check whether this is equivalent to: + // (c1 & m) | (x & ~m) + // where m is a run-of-ones mask. The logic here is that, for each bit in + // c1 and c2: + // - if both are 1, then the output will be 1. + // - if both are 0, then the output will be 0. + // - if the bit in c1 is 0, and the bit in c2 is 1, then the output will + // come from x. + // - if the bit in c1 is 1, and the bit in c2 is 0, then the output will + // be 0. + // If that last condition is never the case, then we can form m from the + // bits that are the same between c1 and c2. + unsigned MB, ME; + if (isRunOfOnes(~(Imm^Imm2), MB, ME) && !(~Imm & Imm2)) { + SDValue Ops[] = { N->getOperand(0).getOperand(0), + N->getOperand(0).getOperand(1), + getI32Imm(0, dl), getI32Imm(MB, dl), + getI32Imm(ME, dl) }; + ReplaceNode(N, CurDAG->getMachineNode(PPC::RLWIMI, dl, MVT::i32, Ops)); + return true; + } + } + } else if (isInt64Immediate(N->getOperand(1).getNode(), Imm64)) { + // If this is a 64-bit zero-extension mask, emit rldicl. + if (isMask_64(Imm64)) { + MB = 64 - countTrailingOnes(Imm64); + SH = 0; + + if (Val.getOpcode() == ISD::ANY_EXTEND) { + auto Op0 = Val.getOperand(0); + if ( Op0.getOpcode() == ISD::SRL && + isInt32Immediate(Op0.getOperand(1).getNode(), Imm) && Imm <= MB) { + + auto ResultType = Val.getNode()->getValueType(0); + auto ImDef = CurDAG->getMachineNode(PPC::IMPLICIT_DEF, dl, + ResultType); + SDValue IDVal (ImDef, 0); + + Val = SDValue(CurDAG->getMachineNode(PPC::INSERT_SUBREG, dl, + ResultType, IDVal, Op0.getOperand(0), + getI32Imm(1, dl)), 0); + SH = 64 - Imm; + } + } + + // If the operand is a logical right shift, we can fold it into this + // instruction: rldicl(rldicl(x, 64-n, n), 0, mb) -> rldicl(x, 64-n, mb) + // for n <= mb. The right shift is really a left rotate followed by a + // mask, and this mask is a more-restrictive sub-mask of the mask implied + // by the shift. + if (Val.getOpcode() == ISD::SRL && + isInt32Immediate(Val.getOperand(1).getNode(), Imm) && Imm <= MB) { + assert(Imm < 64 && "Illegal shift amount"); + Val = Val.getOperand(0); + SH = 64 - Imm; + } + + SDValue Ops[] = { Val, getI32Imm(SH, dl), getI32Imm(MB, dl) }; + CurDAG->SelectNodeTo(N, PPC::RLDICL, MVT::i64, Ops); + return true; + } else if (isMask_64(~Imm64)) { + // If this is a negated 64-bit zero-extension mask, + // i.e. the immediate is a sequence of ones from most significant side + // and all zero for reminder, we should use rldicr. + MB = 63 - countTrailingOnes(~Imm64); + SH = 0; + SDValue Ops[] = { Val, getI32Imm(SH, dl), getI32Imm(MB, dl) }; + CurDAG->SelectNodeTo(N, PPC::RLDICR, MVT::i64, Ops); + return true; + } + + // It is not 16-bit imm that means we need two instructions at least if + // using "and" instruction. Try to exploit it with rotate mask instructions. + if (isRunOfOnes64(Imm64, MB, ME)) { + if (MB >= 32 && MB <= ME) { + // MB ME + // +----------------------+ + // |xxxxxxxxxxx00011111000| + // +----------------------+ + // 0 32 64 + // We can only do it if the MB is larger than 32 and MB <= ME + // as RLWINM will replace the content of [0 - 32) with [32 - 64) even + // we didn't rotate it. + SDValue Ops[] = { Val, getI64Imm(0, dl), getI64Imm(MB - 32, dl), + getI64Imm(ME - 32, dl) }; + CurDAG->SelectNodeTo(N, PPC::RLWINM8, MVT::i64, Ops); + return true; + } + // TODO - handle it with rldicl + rldicl + } + } + + return false; +} + // Select - Convert the specified operand from a target-independent to a // target-specific node if it hasn't already been changed. void PPCDAGToDAGISel::Select(SDNode *N) { @@ -4565,121 +4728,13 @@ void PPCDAGToDAGISel::Select(SDNode *N) { } } - case ISD::AND: { - unsigned Imm, Imm2, SH, MB, ME; - uint64_t Imm64; - - // If this is an and of a value rotated between 0 and 31 bits and then and'd - // with a mask, emit rlwinm - if (isInt32Immediate(N->getOperand(1), Imm) && - isRotateAndMask(N->getOperand(0).getNode(), Imm, false, SH, MB, ME)) { - SDValue Val = N->getOperand(0).getOperand(0); - SDValue Ops[] = { Val, getI32Imm(SH, dl), getI32Imm(MB, dl), - getI32Imm(ME, dl) }; - CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Ops); - return; - } - // If this is just a masked value where the input is not handled above, and - // is not a rotate-left (handled by a pattern in the .td file), emit rlwinm - if (isInt32Immediate(N->getOperand(1), Imm) && - isRunOfOnes(Imm, MB, ME) && - N->getOperand(0).getOpcode() != ISD::ROTL) { - SDValue Val = N->getOperand(0); - SDValue Ops[] = { Val, getI32Imm(0, dl), getI32Imm(MB, dl), - getI32Imm(ME, dl) }; - CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Ops); - return; - } - // If this is a 64-bit zero-extension mask, emit rldicl. - if (isInt64Immediate(N->getOperand(1).getNode(), Imm64) && - isMask_64(Imm64)) { - SDValue Val = N->getOperand(0); - MB = 64 - countTrailingOnes(Imm64); - SH = 0; - - if (Val.getOpcode() == ISD::ANY_EXTEND) { - auto Op0 = Val.getOperand(0); - if ( Op0.getOpcode() == ISD::SRL && - isInt32Immediate(Op0.getOperand(1).getNode(), Imm) && Imm <= MB) { - - auto ResultType = Val.getNode()->getValueType(0); - auto ImDef = CurDAG->getMachineNode(PPC::IMPLICIT_DEF, dl, - ResultType); - SDValue IDVal (ImDef, 0); - - Val = SDValue(CurDAG->getMachineNode(PPC::INSERT_SUBREG, dl, - ResultType, IDVal, Op0.getOperand(0), - getI32Imm(1, dl)), 0); - SH = 64 - Imm; - } - } - - // If the operand is a logical right shift, we can fold it into this - // instruction: rldicl(rldicl(x, 64-n, n), 0, mb) -> rldicl(x, 64-n, mb) - // for n <= mb. The right shift is really a left rotate followed by a - // mask, and this mask is a more-restrictive sub-mask of the mask implied - // by the shift. - if (Val.getOpcode() == ISD::SRL && - isInt32Immediate(Val.getOperand(1).getNode(), Imm) && Imm <= MB) { - assert(Imm < 64 && "Illegal shift amount"); - Val = Val.getOperand(0); - SH = 64 - Imm; - } - - SDValue Ops[] = { Val, getI32Imm(SH, dl), getI32Imm(MB, dl) }; - CurDAG->SelectNodeTo(N, PPC::RLDICL, MVT::i64, Ops); - return; - } - // If this is a negated 64-bit zero-extension mask, - // i.e. the immediate is a sequence of ones from most significant side - // and all zero for reminder, we should use rldicr. - if (isInt64Immediate(N->getOperand(1).getNode(), Imm64) && - isMask_64(~Imm64)) { - SDValue Val = N->getOperand(0); - MB = 63 - countTrailingOnes(~Imm64); - SH = 0; - SDValue Ops[] = { Val, getI32Imm(SH, dl), getI32Imm(MB, dl) }; - CurDAG->SelectNodeTo(N, PPC::RLDICR, MVT::i64, Ops); - return; - } - - // AND X, 0 -> 0, not "rlwinm 32". - if (isInt32Immediate(N->getOperand(1), Imm) && (Imm == 0)) { - ReplaceUses(SDValue(N, 0), N->getOperand(1)); + case ISD::AND: + // If this is an 'and' with a mask, try to emit rlwinm/rldicl/rldicr + if (tryAndWithMask(N)) return; - } - // ISD::OR doesn't get all the bitfield insertion fun. - // (and (or x, c1), c2) where isRunOfOnes(~(c1^c2)) might be a - // bitfield insert. - if (isInt32Immediate(N->getOperand(1), Imm) && - N->getOperand(0).getOpcode() == ISD::OR && - isInt32Immediate(N->getOperand(0).getOperand(1), Imm2)) { - // The idea here is to check whether this is equivalent to: - // (c1 & m) | (x & ~m) - // where m is a run-of-ones mask. The logic here is that, for each bit in - // c1 and c2: - // - if both are 1, then the output will be 1. - // - if both are 0, then the output will be 0. - // - if the bit in c1 is 0, and the bit in c2 is 1, then the output will - // come from x. - // - if the bit in c1 is 1, and the bit in c2 is 0, then the output will - // be 0. - // If that last condition is never the case, then we can form m from the - // bits that are the same between c1 and c2. - unsigned MB, ME; - if (isRunOfOnes(~(Imm^Imm2), MB, ME) && !(~Imm & Imm2)) { - SDValue Ops[] = { N->getOperand(0).getOperand(0), - N->getOperand(0).getOperand(1), - getI32Imm(0, dl), getI32Imm(MB, dl), - getI32Imm(ME, dl) }; - ReplaceNode(N, CurDAG->getMachineNode(PPC::RLWIMI, dl, MVT::i32, Ops)); - return; - } - } // Other cases are autogenerated. break; - } case ISD::OR: { if (N->getValueType(0) == MVT::i32) if (tryBitfieldInsert(N)) @@ -4781,24 +4836,24 @@ void PPCDAGToDAGISel::Select(SDNode *N) { break; } // FIXME: Remove this once the ANDI glue bug is fixed: - case PPCISD::ANDIo_1_EQ_BIT: - case PPCISD::ANDIo_1_GT_BIT: { + case PPCISD::ANDI_rec_1_EQ_BIT: + case PPCISD::ANDI_rec_1_GT_BIT: { if (!ANDIGlueBug) break; EVT InVT = N->getOperand(0).getValueType(); assert((InVT == MVT::i64 || InVT == MVT::i32) && - "Invalid input type for ANDIo_1_EQ_BIT"); + "Invalid input type for ANDI_rec_1_EQ_BIT"); - unsigned Opcode = (InVT == MVT::i64) ? PPC::ANDIo8 : PPC::ANDIo; + unsigned Opcode = (InVT == MVT::i64) ? PPC::ANDI8_rec : PPC::ANDI_rec; SDValue AndI(CurDAG->getMachineNode(Opcode, dl, InVT, MVT::Glue, N->getOperand(0), CurDAG->getTargetConstant(1, dl, InVT)), 0); SDValue CR0Reg = CurDAG->getRegister(PPC::CR0, MVT::i32); - SDValue SRIdxVal = - CurDAG->getTargetConstant(N->getOpcode() == PPCISD::ANDIo_1_EQ_BIT ? - PPC::sub_eq : PPC::sub_gt, dl, MVT::i32); + SDValue SRIdxVal = CurDAG->getTargetConstant( + N->getOpcode() == PPCISD::ANDI_rec_1_EQ_BIT ? PPC::sub_eq : PPC::sub_gt, + dl, MVT::i32); CurDAG->SelectNodeTo(N, TargetOpcode::EXTRACT_SUBREG, MVT::i1, CR0Reg, SRIdxVal, SDValue(AndI.getNode(), 1) /* glue */); @@ -4889,7 +4944,8 @@ void PPCDAGToDAGISel::Select(SDNode *N) { return; } - unsigned BROpc = getPredicateForSetCC(CC); + unsigned BROpc = + getPredicateForSetCC(CC, N->getOperand(0).getValueType(), PPCSubTarget); unsigned SelectCCOp; if (N->getValueType(0) == MVT::i32) @@ -5002,7 +5058,7 @@ void PPCDAGToDAGISel::Select(SDNode *N) { // Prevent PPC::PRED_* from being selected into LI. unsigned PCC = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue(); if (EnableBranchHint) - PCC |= getBranchHint(PCC, FuncInfo, N->getOperand(3)); + PCC |= getBranchHint(PCC, *FuncInfo, N->getOperand(3)); SDValue Pred = getI32Imm(PCC, dl); SDValue Ops[] = { Pred, N->getOperand(2), N->getOperand(3), @@ -5012,7 +5068,8 @@ void PPCDAGToDAGISel::Select(SDNode *N) { } case ISD::BR_CC: { ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(1))->get(); - unsigned PCC = getPredicateForSetCC(CC); + unsigned PCC = + getPredicateForSetCC(CC, N->getOperand(2).getValueType(), PPCSubTarget); if (N->getOperand(2).getValueType() == MVT::i1) { unsigned Opc; @@ -5045,7 +5102,7 @@ void PPCDAGToDAGISel::Select(SDNode *N) { } if (EnableBranchHint) - PCC |= getBranchHint(PCC, FuncInfo, N->getOperand(4)); + PCC |= getBranchHint(PCC, *FuncInfo, N->getOperand(4)); SDValue CondCode = SelectCC(N->getOperand(2), N->getOperand(3), CC, dl); SDValue Ops[] = { getI32Imm(PCC, dl), CondCode, @@ -6181,8 +6238,8 @@ static bool PeepholePPC64ZExtGather(SDValue Op32, // For ANDI and ANDIS, the higher-order bits are zero if either that is true // of the first operand, or if the second operand is positive (so that it is // not sign extended). - if (Op32.getMachineOpcode() == PPC::ANDIo || - Op32.getMachineOpcode() == PPC::ANDISo) { + if (Op32.getMachineOpcode() == PPC::ANDI_rec || + Op32.getMachineOpcode() == PPC::ANDIS_rec) { SmallPtrSet<SDNode *, 16> ToPromote1; bool Op0OK = PeepholePPC64ZExtGather(Op32.getOperand(0), ToPromote1); @@ -6304,8 +6361,12 @@ void PPCDAGToDAGISel::PeepholePPC64ZExt() { case PPC::ORI: NewOpcode = PPC::ORI8; break; case PPC::ORIS: NewOpcode = PPC::ORIS8; break; case PPC::AND: NewOpcode = PPC::AND8; break; - case PPC::ANDIo: NewOpcode = PPC::ANDIo8; break; - case PPC::ANDISo: NewOpcode = PPC::ANDISo8; break; + case PPC::ANDI_rec: + NewOpcode = PPC::ANDI8_rec; + break; + case PPC::ANDIS_rec: + NewOpcode = PPC::ANDIS8_rec; + break; } // Note: During the replacement process, the nodes will be in an |