[PATCH] D143887: [BOLT][AArch64] Replace NOP with adrp in AdrRelaxationPass to preserve relative offsets.

Denis Revunov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 13 01:32:46 PST 2023


treapster created this revision.
treapster added a project: bolt.
Herald added subscribers: ayermolo, kristof.beyls.
Herald added a reviewer: rafauler.
Herald added a reviewer: Amir.
Herald added a reviewer: maksfb.
Herald added a project: All.
treapster requested review of this revision.
Herald added subscribers: llvm-commits, yota9.
Herald added a project: LLVM.

Avoid replacing one adr instruction with two adrp+add by utilizing linker-provided nops when they are present. By doing so we preserve relative offsets of next instructions in a function which reduces chances to break undetected jump tables. This commit makes release-mode lld-linked clang, lld and etc work after BOLT, because they have jump tables which rely on offsets in a function.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D143887

Files:
  bolt/lib/Passes/ADRRelaxationPass.cpp
  bolt/test/runtime/AArch64/adrrelaxationpass.s


Index: bolt/test/runtime/AArch64/adrrelaxationpass.s
===================================================================
--- bolt/test/runtime/AArch64/adrrelaxationpass.s
+++ bolt/test/runtime/AArch64/adrrelaxationpass.s
@@ -1,5 +1,8 @@
 # The second and third ADR instructions are non-local to functions
 # and must be replaced with ADRP + ADD by BOLT
+# Also since main is non-simple, we can't change it's length so we have to
+# replace NOP with adrp, and if there is no nop before adr in non-simple function,
+# we can't guarantee we didn't break possible jump tables so we fail in strict mode
 
 # REQUIRES: system-linux
 
@@ -9,7 +12,7 @@
 # RUN: llvm-bolt %t.exe -o %t.bolt --adr-relaxation=true
 # RUN: llvm-objdump --no-print-imm-hex -d --disassemble-symbols=main %t.bolt | FileCheck %s
 # RUN: %t.bolt
-
+# RUN: not llvm-bolt %t.exe -o %t.bolt --adr-relaxation=true --strict 2>&1 | FileCheck %s --check-prefix CHECK-ERROR
   .data
   .align 8
   .global Gvar
@@ -31,6 +34,7 @@
   .type main, %function
 main:
   adr x0, .CI
+  nop
   adr x1, test
   adr x2, Gvar2
   adr x3, br
@@ -47,3 +51,4 @@
 # CHECK-NEXT: adrp x2, 0x{{[1-8a-f][0-9a-f]*}}
 # CHECK-NEXT: add x2, x2, #{{[1-8a-f][0-9a-f]*}}
 # CHECK-NEXT: adr x3, #{{[0-9][0-9]*}}
+# CHECK-ERROR: BOLT-ERROR: Cannot relax adr in non-simple function main
Index: bolt/lib/Passes/ADRRelaxationPass.cpp
===================================================================
--- bolt/lib/Passes/ADRRelaxationPass.cpp
+++ bolt/lib/Passes/ADRRelaxationPass.cpp
@@ -12,6 +12,8 @@
 
 #include "bolt/Passes/ADRRelaxationPass.h"
 #include "bolt/Core/ParallelUtilities.h"
+#include "bolt/Utils/CommandLineOpts.h"
+#include <iterator>
 
 using namespace llvm;
 
@@ -54,6 +56,20 @@
       int64_t Addend = BC.MIB->getTargetAddend(Inst);
       InstructionListType Addr =
           BC.MIB->materializeAddress(Symbol, BC.Ctx.get(), Reg, Addend);
+
+      if (It != BB.begin() && BC.MIB->isNoop(*std::prev(It))) {
+        It = BB.eraseInstruction(std::prev(It));
+      } else if (opts::StrictMode && !BF.isSimple()) {
+        // If the function is not simple, it may contain a jump table undetected
+        // by us. This jump table may use an offset from the branch instruction
+        // to land in the desired place. If we add new instructions, we
+        // invalidate this offset, so we have to rely on linker-inserted NOP to
+        // replace it with ADRP, and abort if it is not present.
+        errs() << formatv("BOLT-ERROR: Cannot relax adr in non-simple function "
+                          "{0}. Can't proceed in current mode.\n",
+                          BF.getOneName());
+        exit(1);
+      }
       It = BB.replaceInstruction(It, Addr);
     }
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D143887.496869.patch
Type: text/x-patch
Size: 2726 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230213/e4405fa0/attachment.bin>


More information about the llvm-commits mailing list