1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

AArch64: materialize large stack offset into xzr correctly.

When a stack offset was too big to materialize in a single instruction, we were
trying to do it in stages:

    adds xD, sp, #imm
    adds xD, xD, #imm

Unfortunately, if xD is xzr then the second instruction doesn't exist and
wouldn't do what was needed if it did. Instead we can use a temporary register
for all but the last addition.
This commit is contained in:
Tim Northover 2020-04-22 14:02:48 +01:00
parent ffa794c4cb
commit 8b6ab03c03
2 changed files with 35 additions and 5 deletions

View File

@ -3332,6 +3332,10 @@ static void emitFrameOffsetAdj(MachineBasicBlock &MBB,
// assert(Offset < (1 << 24) && "unimplemented reg plus immediate");
const unsigned MaxEncodableValue = MaxEncoding << ShiftSize;
Register TmpReg = DestReg;
if (TmpReg == AArch64::XZR)
TmpReg = MBB.getParent()->getRegInfo().createVirtualRegister(
&AArch64::GPR64RegClass);
do {
uint64_t ThisVal = std::min<uint64_t>(Offset, MaxEncodableValue);
unsigned LocalShiftSize = 0;
@ -3341,7 +3345,11 @@ static void emitFrameOffsetAdj(MachineBasicBlock &MBB,
}
assert((ThisVal >> ShiftSize) <= MaxEncoding &&
"Encoding cannot handle value that big");
auto MBI = BuildMI(MBB, MBBI, DL, TII->get(Opc), DestReg)
Offset -= ThisVal << LocalShiftSize;
if (Offset == 0)
TmpReg = DestReg;
auto MBI = BuildMI(MBB, MBBI, DL, TII->get(Opc), TmpReg)
.addReg(SrcReg)
.addImm(Sign * (int)ThisVal);
if (ShiftSize)
@ -3362,8 +3370,8 @@ static void emitFrameOffsetAdj(MachineBasicBlock &MBB,
BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_AddFP))
.addImm(Imm)
.setMIFlag(Flag);
assert((Offset - Imm) == 0 && "Expected remaining offset to be zero to "
"emit a single SEH directive");
assert(Offset == 0 && "Expected remaining offset to be zero to "
"emit a single SEH directive");
} else if (DestReg == AArch64::SP) {
if (HasWinCFI)
*HasWinCFI = true;
@ -3376,8 +3384,7 @@ static void emitFrameOffsetAdj(MachineBasicBlock &MBB,
*HasWinCFI = true;
}
SrcReg = DestReg;
Offset -= ThisVal << LocalShiftSize;
SrcReg = TmpReg;
} while (Offset);
}

View File

@ -0,0 +1,23 @@
; RUN: llc -mtriple=arm64-apple-ios %s -o - | FileCheck %s
define void @foo() {
; CHECK-LABEL: foo:
; CHECK: adds [[TMP:x[0-9]+]], sp,
; CHECK: cmn [[TMP]],
%var = alloca i32, i32 12
%var2 = alloca i32, i32 1030
%tst = icmp eq i32* %var, null
br i1 %tst, label %true, label %false
true:
call void @bar()
ret void
false:
call void @baz()
ret void
}
declare void @bar()
declare void @baz()