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:
parent
ffa794c4cb
commit
8b6ab03c03
@ -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);
|
||||
}
|
||||
|
||||
|
23
test/CodeGen/AArch64/large-stack-cmp.ll
Normal file
23
test/CodeGen/AArch64/large-stack-cmp.ll
Normal 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()
|
Loading…
x
Reference in New Issue
Block a user