Index: llvm/trunk/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp +++ llvm/trunk/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp @@ -897,9 +897,14 @@ case AArch64::MOVi64imm: return expandMOVImm(MBB, MBBI, 64); case AArch64::RET_ReallyLR: { + // Hiding the LR use with RET_ReallyLR may lead to extra kills in the + // function and missing live-ins. We are fine in practice because callee + // saved register handling ensures the register value is restored before + // RET, but we need the undef flag here to appease the MachineVerifier + // liveness checks. MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::RET)) - .addReg(AArch64::LR); + .addReg(AArch64::LR, RegState::Undef); transferImpOps(MI, MIB, MIB); MI.eraseFromParent(); return true; Index: llvm/trunk/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp +++ llvm/trunk/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp @@ -767,6 +767,7 @@ // Remove the load, if the destination register of the loads is the same // register for stored value. if (StRt == LdRt && LoadSize == 8) { + StoreI->clearRegisterKills(StRt, TRI); DEBUG(dbgs() << "Remove load instruction:\n "); DEBUG(LoadI->print(dbgs())); DEBUG(dbgs() << "\n"); @@ -831,6 +832,8 @@ .addImm(Imms); } } + StoreI->clearRegisterKills(StRt, TRI); + (void)BitExtMI; DEBUG(dbgs() << "Promoting load by replacing :\n "); Index: llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.h =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.h +++ llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.h @@ -95,6 +95,10 @@ unsigned getRegPressureLimit(const TargetRegisterClass *RC, MachineFunction &MF) const override; + + bool trackLivenessAfterRegAlloc(const MachineFunction&) const override { + return true; + } }; } // end namespace llvm Index: llvm/trunk/test/CodeGen/AArch64/ldst-opt-dbg-limit.mir =================================================================== --- llvm/trunk/test/CodeGen/AArch64/ldst-opt-dbg-limit.mir +++ llvm/trunk/test/CodeGen/AArch64/ldst-opt-dbg-limit.mir @@ -28,7 +28,7 @@ name: promote-load-from-store alignment: 2 exposesReturnsTwice: false -tracksRegLiveness: false +tracksRegLiveness: true liveins: - { reg: '%x0' } - { reg: '%w1' } @@ -48,7 +48,7 @@ hasMustTailInVarArgFunc: false body: | bb.0 (%ir-block.0): - liveins: %w1, %x0 + liveins: %w1, %x0, %lr STRWui killed %w1, %x0, 0 :: (store 4 into %ir.dst) CFI_INSTRUCTION 0 @@ -76,13 +76,13 @@ ... # CHECK-LABEL: name: promote-load-from-store -# CHECK: STRWui killed %w1 +# CHECK: STRWui %w1 # CHECK: UBFMWri %w1 --- name: store-pair alignment: 2 exposesReturnsTwice: false -tracksRegLiveness: false +tracksRegLiveness: true liveins: - { reg: '%x0' } - { reg: '%w1' } @@ -102,7 +102,7 @@ hasMustTailInVarArgFunc: false body: | bb.0 (%ir-block.0): - liveins: %w1, %x0 + liveins: %w1, %x0, %lr STRWui %w1, %x0, 0 :: (store 4 into %ir.dst01) CFI_INSTRUCTION 0 Index: llvm/trunk/test/CodeGen/AArch64/movimm-wzr.mir =================================================================== --- llvm/trunk/test/CodeGen/AArch64/movimm-wzr.mir +++ llvm/trunk/test/CodeGen/AArch64/movimm-wzr.mir @@ -39,4 +39,4 @@ ... # CHECK: bb.0 -# CHECK-NEXT: RET %lr +# CHECK-NEXT: RET undef %lr