[llvm] dace822 - AArch64: materialize large stack offset into xzr correctly.
Tim Northover via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 1 02:00:14 PDT 2020
Author: Tim Northover
Date: 2020-06-01T09:30:05+01:00
New Revision: dace8224f38a31636a02fe9c2af742222831f70c
URL: https://github.com/llvm/llvm-project/commit/dace8224f38a31636a02fe9c2af742222831f70c
DIFF: https://github.com/llvm/llvm-project/commit/dace8224f38a31636a02fe9c2af742222831f70c.diff
LOG: 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.
Added:
llvm/test/CodeGen/AArch64/large-stack-cmp.ll
Modified:
llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index fd07c32e5496..801f162937ed 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -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);
}
diff --git a/llvm/test/CodeGen/AArch64/large-stack-cmp.ll b/llvm/test/CodeGen/AArch64/large-stack-cmp.ll
new file mode 100644
index 000000000000..68a76b79df93
--- /dev/null
+++ b/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()
More information about the llvm-commits
mailing list