[llvm] c93d50d - AArch64: use a constpool for blockaddress(...) on MachO

Tim Northover via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 8 07:13:37 PST 2021


Author: Tim Northover
Date: 2021-02-08T15:13:29Z
New Revision: c93d50dd716879a7edb2c28f4bf9d435651f3766

URL: https://github.com/llvm/llvm-project/commit/c93d50dd716879a7edb2c28f4bf9d435651f3766
DIFF: https://github.com/llvm/llvm-project/commit/c93d50dd716879a7edb2c28f4bf9d435651f3766.diff

LOG: AArch64: use a constpool for blockaddress(...) on MachO

More MachO madness for everyone. MachO relocations are only 32-bits, which
means the ARM64_RELOC_ADDEND one only actually has 24 (signed) bits for the
actual addend. This is a problem when calculating the address of a basic block;
because it has no symbol of its own, the sequence

	adrp x0, Ltmp0 at PAGE
	add x0, x0, x0 Ltmp0 at PAGEOFF

is represented by relocation with an addend that contains the offset from the
function start to Ltmp, and so the largest function where this is guaranteed to
work is 8MB. That's not quite big enough that we can call it user error (IMO).

So this patch puts the any blockaddress into a constant-pool, where the addend
is instead stored in the (x)word being relocated, which is obviously big enough
for any function.

Added: 
    

Modified: 
    llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
    llvm/test/CodeGen/AArch64/arm64-blockaddress.ll
    llvm/test/CodeGen/AArch64/arm64_32.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
index e57650ae60b1..f72d3cfcc6a4 100644
--- a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
@@ -23,6 +23,7 @@
 #include "llvm/ADT/Triple.h"
 #include "llvm/CodeGen/LivePhysRegs.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstr.h"
@@ -877,11 +878,36 @@ bool AArch64ExpandPseudo::expandMI(MachineBasicBlock &MBB,
     MI.eraseFromParent();
     return true;
   }
+  case AArch64::MOVaddrBA: {
+    MachineFunction &MF = *MI.getParent()->getParent();
+    if (MF.getSubtarget<AArch64Subtarget>().isTargetMachO()) {
+      // blockaddress expressions have to come from a constant pool because the
+      // largest addend (and hence offset within a function) allowed for ADRP is
+      // only 8MB.
+      const BlockAddress *BA = MI.getOperand(1).getBlockAddress();
+      assert(MI.getOperand(1).getOffset() == 0 && "unexpected offset");
+
+      MachineConstantPool *MCP = MF.getConstantPool();
+      unsigned CPIdx = MCP->getConstantPoolIndex(BA, Align(8));
 
+      Register DstReg = MI.getOperand(0).getReg();
+      auto MIB1 =
+          BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::ADRP), DstReg)
+              .addConstantPoolIndex(CPIdx, 0, AArch64II::MO_PAGE);
+      auto MIB2 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
+                          TII->get(AArch64::LDRXui), DstReg)
+                      .addUse(DstReg)
+                      .addConstantPoolIndex(
+                          CPIdx, 0, AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
+      transferImpOps(MI, MIB1, MIB2);
+      MI.eraseFromParent();
+      return true;
+    }
+  }
+    LLVM_FALLTHROUGH;
   case AArch64::MOVaddr:
   case AArch64::MOVaddrJT:
   case AArch64::MOVaddrCP:
-  case AArch64::MOVaddrBA:
   case AArch64::MOVaddrTLS:
   case AArch64::MOVaddrEXT: {
     // Expand into ADRP + ADD.

diff  --git a/llvm/test/CodeGen/AArch64/arm64-blockaddress.ll b/llvm/test/CodeGen/AArch64/arm64-blockaddress.ll
index b35cb28b4726..68b8fcbefc5a 100644
--- a/llvm/test/CodeGen/AArch64/arm64-blockaddress.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-blockaddress.ll
@@ -1,4 +1,5 @@
-; RUN: llc < %s -mtriple=arm64-apple-ios | FileCheck %s
+; RUN: llc < %s -mtriple=arm64-apple-ios | FileCheck %s --check-prefix=CHECK-IOS
+; RUN: llc < %s -mtriple=arm64-apple-ios -global-isel | FileCheck %s --check-prefix=CHECK-IOS
 ; RUN: llc < %s -mtriple=arm64-linux-gnu | FileCheck %s --check-prefix=CHECK-LINUX
 ; RUN: llc < %s -mtriple=arm64-linux-gnu -code-model=large| FileCheck %s --check-prefix=CHECK-LARGE
 
@@ -6,9 +7,11 @@
 
 define i64 @t() nounwind ssp {
 entry:
-; CHECK-LABEL: t:
-; CHECK: adrp [[REG:x[0-9]+]], Ltmp0 at PAGE
-; CHECK: add {{x[0-9]+}}, [[REG]], Ltmp0 at PAGEOFF
+; CHECK-IOS: lCPI0_0:
+; CHECK-IOS:     .quad Ltmp0
+; CHECK-IOS-LABEL: _t:
+; CHECK-IOS: adrp x[[TMP:[0-9]+]], lCPI0_0 at PAGE
+; CHECK-IOS: ldr {{x[0-9]+}}, [x[[TMP]], lCPI0_0 at PAGEOFF]
 
 ; CHECK-LINUX-LABEL: t:
 ; CHECK-LINUX: adrp [[REG:x[0-9]+]], .Ltmp0

diff  --git a/llvm/test/CodeGen/AArch64/arm64_32.ll b/llvm/test/CodeGen/AArch64/arm64_32.ll
index 7853229d924d..b5c2c6ebb81d 100644
--- a/llvm/test/CodeGen/AArch64/arm64_32.ll
+++ b/llvm/test/CodeGen/AArch64/arm64_32.ll
@@ -452,8 +452,8 @@ define double @test_constpool() {
 define i8* @test_blockaddress() {
 ; CHECK-LABEL: test_blockaddress:
 ; CHECK: [[BLOCK:Ltmp[0-9]+]]:
-; CHECK: adrp [[PAGE:x[0-9]+]], [[BLOCK]]@PAGE
-; CHECK: add x0, [[PAGE]], [[BLOCK]]@PAGEOFF
+; CHECK: adrp x[[PAGE:[0-9]+]], lCPI{{[0-9]+_[0-9]+}}@PAGE
+; CHECK: ldr x0, [x[[PAGE]], lCPI{{[0-9]+_[0-9]+}}@PAGEOFF]
   br label %dest
 dest:
   ret i8* blockaddress(@test_blockaddress, %dest)


        


More information about the llvm-commits mailing list