[PATCH] D78634: AArch64: materialize large stack offset into xzr correctly.
Tim Northover via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 22 06:28:52 PDT 2020
t.p.northover created this revision.
Herald added subscribers: danielkiss, hiraditya, kristof.beyls, mcrosier.
Herald added a project: LLVM.
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 (`adds xzr, xzr, #imm`) 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.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D78634
Files:
llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
llvm/test/CodeGen/AArch64/large-stack-cmp.ll
Index: llvm/test/CodeGen/AArch64/large-stack-cmp.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/AArch64/large-stack-cmp.ll
@@ -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()
Index: llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -3221,6 +3221,10 @@
// 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;
@@ -3230,7 +3234,11 @@
}
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)
@@ -3251,8 +3259,8 @@
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;
@@ -3265,8 +3273,7 @@
*HasWinCFI = true;
}
- SrcReg = DestReg;
- Offset -= ThisVal << LocalShiftSize;
+ SrcReg = TmpReg;
} while (Offset);
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D78634.259261.patch
Type: text/x-patch
Size: 2452 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200422/a362a24f/attachment.bin>
More information about the llvm-commits
mailing list