mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 04:33:05 +00:00
Fix a bug in the Thumb1 ARM Load/Store optimizer
Previously, the basic block was searched for future uses of the base register, and if necessary any writeback to the base register was reset using a SUB instruction (e.g. before calling a function) just before such a use. However, this step happened *before* the merged LDM/STM instruction was built. So if there was (e.g.) a function call directly after the not-yet-formed LDM/STM, the pass would first insert a SUB instruction to reset the base register, and then (at the same location, incorrectly) insert the LDM/STM itself. This patch fixes PR19972. Patch by Moritz Roth. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210542 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
102d0f3e3f
commit
2d89932fb2
@ -505,7 +505,7 @@ ARMLoadStoreOpt::MergeOps(MachineBasicBlock &MBB,
|
|||||||
|
|
||||||
// Exception: If the base register is in the input reglist, Thumb1 LDM is
|
// Exception: If the base register is in the input reglist, Thumb1 LDM is
|
||||||
// non-writeback. Check for this.
|
// non-writeback. Check for this.
|
||||||
if (Opcode == ARM::tLDRi && isThumb1)
|
if (Opcode == ARM::tLDMIA && isThumb1)
|
||||||
for (unsigned I = 0; I < NumRegs; ++I)
|
for (unsigned I = 0; I < NumRegs; ++I)
|
||||||
if (Base == Regs[I].first) {
|
if (Base == Regs[I].first) {
|
||||||
Writeback = false;
|
Writeback = false;
|
||||||
@ -519,17 +519,17 @@ ARMLoadStoreOpt::MergeOps(MachineBasicBlock &MBB,
|
|||||||
// Update tLDMIA with writeback if necessary.
|
// Update tLDMIA with writeback if necessary.
|
||||||
Opcode = ARM::tLDMIA_UPD;
|
Opcode = ARM::tLDMIA_UPD;
|
||||||
|
|
||||||
// The base isn't dead after a merged instruction with writeback. Update
|
|
||||||
// future uses of the base with the added offset (if possible), or reset
|
|
||||||
// the base register as necessary.
|
|
||||||
if (!BaseKill)
|
|
||||||
UpdateBaseRegUses(MBB, MBBI, dl, Base, NumRegs, Pred, PredReg);
|
|
||||||
|
|
||||||
MIB = BuildMI(MBB, MBBI, dl, TII->get(Opcode));
|
MIB = BuildMI(MBB, MBBI, dl, TII->get(Opcode));
|
||||||
|
|
||||||
// Thumb1: we might need to set base writeback when building the MI.
|
// Thumb1: we might need to set base writeback when building the MI.
|
||||||
MIB.addReg(Base, getDefRegState(true))
|
MIB.addReg(Base, getDefRegState(true))
|
||||||
.addReg(Base, getKillRegState(BaseKill));
|
.addReg(Base, getKillRegState(BaseKill));
|
||||||
|
|
||||||
|
// The base isn't dead after a merged instruction with writeback. Update
|
||||||
|
// future uses of the base with the added offset (if possible), or reset
|
||||||
|
// the base register as necessary.
|
||||||
|
if (!BaseKill)
|
||||||
|
UpdateBaseRegUses(MBB, MBBI, dl, Base, NumRegs, Pred, PredReg);
|
||||||
} else {
|
} else {
|
||||||
// No writeback, simply build the MachineInstr.
|
// No writeback, simply build the MachineInstr.
|
||||||
MIB = BuildMI(MBB, MBBI, dl, TII->get(Opcode));
|
MIB = BuildMI(MBB, MBBI, dl, TII->get(Opcode));
|
||||||
|
17
test/CodeGen/Thumb/2014-06-10-thumb1-ldst-opt-bug.ll
Normal file
17
test/CodeGen/Thumb/2014-06-10-thumb1-ldst-opt-bug.ll
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
; RUN: llc < %s -mtriple=thumbv6m-eabi -o - | FileCheck %s
|
||||||
|
|
||||||
|
define void @foo(i32* %A) #0 {
|
||||||
|
entry:
|
||||||
|
; CHECK-LABEL: foo:
|
||||||
|
; CHECK: push {r7, lr}
|
||||||
|
; CHECK: ldm [[REG0:r[0-9]]]!,
|
||||||
|
; CHECK-NEXT: subs [[REG0]]
|
||||||
|
; CHECK-NEXT: bl
|
||||||
|
%0 = load i32* %A, align 4
|
||||||
|
%arrayidx1 = getelementptr inbounds i32* %A, i32 1
|
||||||
|
%1 = load i32* %arrayidx1, align 4
|
||||||
|
tail call void @bar(i32* %A, i32 %0, i32 %1) #2
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @bar(i32*, i32, i32) #1
|
Loading…
Reference in New Issue
Block a user