Index: lib/Target/ARM/ARMLoadStoreOptimizer.cpp =================================================================== --- lib/Target/ARM/ARMLoadStoreOptimizer.cpp +++ lib/Target/ARM/ARMLoadStoreOptimizer.cpp @@ -1559,12 +1559,10 @@ static void InsertLDR_STR(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, int Offset, - bool isDef, const DebugLoc &DL, unsigned NewOpc, - unsigned Reg, bool RegDeadKill, bool RegUndef, - unsigned BaseReg, bool BaseKill, bool BaseUndef, - bool OffKill, bool OffUndef, ARMCC::CondCodes Pred, - unsigned PredReg, const TargetInstrInfo *TII, - bool isT2) { + bool isDef, unsigned NewOpc, unsigned Reg, + bool RegDeadKill, bool RegUndef, unsigned BaseReg, + bool BaseKill, bool BaseUndef, ARMCC::CondCodes Pred, + unsigned PredReg, const TargetInstrInfo *TII) { if (isDef) { MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(NewOpc)) @@ -1584,6 +1582,8 @@ MachineBasicBlock::iterator &MBBI) { MachineInstr *MI = &*MBBI; unsigned Opcode = MI->getOpcode(); + // FIXME: Code/comments below check Opcode == t2STRDi8, but this check returns + // if we see this opcode. if (Opcode != ARM::LDRD && Opcode != ARM::STRD && Opcode != ARM::t2LDRDi8) return false; @@ -1615,8 +1615,8 @@ bool OddUndef = MI->getOperand(1).isUndef(); bool BaseKill = BaseOp.isKill(); bool BaseUndef = BaseOp.isUndef(); - bool OffKill = isT2 ? false : MI->getOperand(3).isKill(); - bool OffUndef = isT2 ? false : MI->getOperand(3).isUndef(); + assert((isT2 || MI->getOperand(3).getReg() == ARM::NoRegister) && + "register offset not handled below"); int OffImm = getMemoryOpOffset(*MI); unsigned PredReg = 0; ARMCC::CondCodes Pred = getInstrPredicate(*MI, PredReg); @@ -1654,21 +1654,14 @@ unsigned NewOpc2 = (isLd) ? (isT2 ? (OffImm+4 < 0 ? ARM::t2LDRi8 : ARM::t2LDRi12) : ARM::LDRi12) : (isT2 ? (OffImm+4 < 0 ? ARM::t2STRi8 : ARM::t2STRi12) : ARM::STRi12); - DebugLoc dl = MBBI->getDebugLoc(); - // If this is a load and base register is killed, it may have been - // re-defed by the load, make sure the first load does not clobber it. - if (isLd && - (BaseKill || OffKill) && - (TRI->regsOverlap(EvenReg, BaseReg))) { + // If this is a load, make sure the first load does not clobber the base + // register before the second load reads it. + if (isLd && TRI->regsOverlap(EvenReg, BaseReg)) { assert(!TRI->regsOverlap(OddReg, BaseReg)); - InsertLDR_STR(MBB, MBBI, OffImm+4, isLd, dl, NewOpc2, - OddReg, OddDeadKill, false, - BaseReg, false, BaseUndef, false, OffUndef, - Pred, PredReg, TII, isT2); - InsertLDR_STR(MBB, MBBI, OffImm, isLd, dl, NewOpc, - EvenReg, EvenDeadKill, false, - BaseReg, BaseKill, BaseUndef, OffKill, OffUndef, - Pred, PredReg, TII, isT2); + InsertLDR_STR(MBB, MBBI, OffImm + 4, isLd, NewOpc2, OddReg, OddDeadKill, + false, BaseReg, false, BaseUndef, Pred, PredReg, TII); + InsertLDR_STR(MBB, MBBI, OffImm, isLd, NewOpc, EvenReg, EvenDeadKill, + false, BaseReg, BaseKill, BaseUndef, Pred, PredReg, TII); } else { if (OddReg == EvenReg && EvenDeadKill) { // If the two source operands are the same, the kill marker is @@ -1680,14 +1673,10 @@ // Never kill the base register in the first instruction. if (EvenReg == BaseReg) EvenDeadKill = false; - InsertLDR_STR(MBB, MBBI, OffImm, isLd, dl, NewOpc, - EvenReg, EvenDeadKill, EvenUndef, - BaseReg, false, BaseUndef, false, OffUndef, - Pred, PredReg, TII, isT2); - InsertLDR_STR(MBB, MBBI, OffImm+4, isLd, dl, NewOpc2, - OddReg, OddDeadKill, OddUndef, - BaseReg, BaseKill, BaseUndef, OffKill, OffUndef, - Pred, PredReg, TII, isT2); + InsertLDR_STR(MBB, MBBI, OffImm, isLd, NewOpc, EvenReg, EvenDeadKill, + EvenUndef, BaseReg, false, BaseUndef, Pred, PredReg, TII); + InsertLDR_STR(MBB, MBBI, OffImm + 4, isLd, NewOpc2, OddReg, OddDeadKill, + OddUndef, BaseReg, BaseKill, BaseUndef, Pred, PredReg, TII); } if (isLd) ++NumLDRD2LDR; Index: test/CodeGen/ARM/load_store_opt_kill.mir =================================================================== --- /dev/null +++ test/CodeGen/ARM/load_store_opt_kill.mir @@ -0,0 +1,12 @@ +# RUN: llc -mtriple=armv7-none-eabi -verify-machineinstrs -run-pass arm-ldst-opt %s -o - | FileCheck %s +--- +# CHECK-LABEL: name: f +name: f +# Make sure the load into %r0 doesn't clobber the base register before the second load uses it. +# CHECK: %r3 = LDRi12 %r0, 12, 14, _ +# CHECK-NEXT: %r0 = LDRi12 %r0, 8, 14, _ +body: | + bb.0: + liveins: %r0, %r3 + %r0, %r3 = LDRD %r0, %noreg, 8, 14, %noreg +...