[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