diff --git a/lib/CodeGen/PeepholeOptimizer.cpp b/lib/CodeGen/PeepholeOptimizer.cpp index 495ed67397d..ae14331d663 100644 --- a/lib/CodeGen/PeepholeOptimizer.cpp +++ b/lib/CodeGen/PeepholeOptimizer.cpp @@ -161,9 +161,10 @@ namespace { /// \brief Check whether \p MI is a copy like instruction that is /// not recognized by the register coalescer. bool isUncoalescableCopy(const MachineInstr &MI) { - return MI.isBitcast() || (!DisableAdvCopyOpt && - (MI.isRegSequenceLike() || - MI.isExtractSubregLike())); + return MI.isBitcast() || + (!DisableAdvCopyOpt && + (MI.isRegSequenceLike() || MI.isInsertSubregLike() || + MI.isExtractSubregLike())); } }; @@ -1271,44 +1272,26 @@ bool ValueTracker::getNextSourceFromRegSequence(unsigned &SrcReg, return false; } -/// Extract the inputs from INSERT_SUBREG. -/// INSERT_SUBREG vreg0:sub0, vreg1:sub1, sub3 would produce: -/// - BaseReg: vreg0:sub0 -/// - InsertedReg: vreg1:sub1, sub3 -static void -getInsertSubregInputs(const MachineInstr &MI, - TargetInstrInfo::RegSubRegPair &BaseReg, - TargetInstrInfo::RegSubRegPairAndIdx &InsertedReg) { - assert(MI.isInsertSubreg() && "Instruction do not have the proper type"); - - // We are looking at: - // Def = INSERT_SUBREG v0, v1, sub0. - const MachineOperand &MOBaseReg = MI.getOperand(1); - const MachineOperand &MOInsertedReg = MI.getOperand(2); - const MachineOperand &MOSubIdx = MI.getOperand(3); - assert(MOSubIdx.isImm() && - "One of the subindex of the reg_sequence is not an immediate"); - BaseReg.Reg = MOBaseReg.getReg(); - BaseReg.SubReg = MOBaseReg.getSubReg(); - - InsertedReg.Reg = MOInsertedReg.getReg(); - InsertedReg.SubReg = MOInsertedReg.getSubReg(); - InsertedReg.SubIdx = (unsigned)MOSubIdx.getImm(); -} - bool ValueTracker::getNextSourceFromInsertSubreg(unsigned &SrcReg, unsigned &SrcSubReg) { - assert(Def->isInsertSubreg() && "Invalid definition"); + assert((Def->isInsertSubreg() || Def->isInsertSubregLike()) && + "Invalid definition"); + if (Def->getOperand(DefIdx).getSubReg()) // If we are composing subreg, bails out. // Same remark as getNextSourceFromRegSequence. // I.e., this may be turned into an assert. return false; + if (!TII) + // We could handle the REG_SEQUENCE here, but we do not want to + // duplicate the code from the generic TII. + return false; + TargetInstrInfo::RegSubRegPair BaseReg; TargetInstrInfo::RegSubRegPairAndIdx InsertedReg; - assert(DefIdx == 0 && "Invalid definition"); - getInsertSubregInputs(*Def, BaseReg, InsertedReg); + if (!TII->getInsertSubregInputs(*Def, DefIdx, BaseReg, InsertedReg)) + return false; // We are looking at: // Def = INSERT_SUBREG v0, v1, sub1 @@ -1416,7 +1399,7 @@ bool ValueTracker::getNextSourceImpl(unsigned &SrcReg, unsigned &SrcSubReg) { return false; if (Def->isRegSequence() || Def->isRegSequenceLike()) return getNextSourceFromRegSequence(SrcReg, SrcSubReg); - if (Def->isInsertSubreg()) + if (Def->isInsertSubreg() || Def->isInsertSubregLike()) return getNextSourceFromInsertSubreg(SrcReg, SrcSubReg); if (Def->isExtractSubreg() || Def->isExtractSubregLike()) return getNextSourceFromExtractSubreg(SrcReg, SrcSubReg); diff --git a/test/CodeGen/ARM/adv-copy-opt.ll b/test/CodeGen/ARM/adv-copy-opt.ll index c9a9b831d0e..c618d40efa8 100644 --- a/test/CodeGen/ARM/adv-copy-opt.ll +++ b/test/CodeGen/ARM/adv-copy-opt.ll @@ -26,11 +26,8 @@ ; NOOPT-NEXT: bx lr ; ; OPT-NOT: vmov -; OPT: udiv [[RES_LOW:r[0-9]+]], r0, r2 -; OPT-NEXT: udiv [[RES_HIGH:r[0-9]+]], r1, r3 -; OPT-NEXT: vmov.32 [[RES:d[0-9]+]][0], [[RES_LOW]] -; OPT-NEXT: vmov.32 [[RES]][1], [[RES_HIGH]] -; OPT-NEXT: vmov r0, r1, [[RES]] +; OPT: udiv r0, r0, r2 +; OPT-NEXT: udiv r1, r1, r3 ; OPT-NEXT: bx lr define <2 x i32> @simpleVectorDiv(<2 x i32> %A, <2 x i32> %B) nounwind { entry: