-
Notifications
You must be signed in to change notification settings - Fork 15.3k
Reapply "[BOLT][BTI] Skip inlining BasicBlocks containing indirect tailcalls" (#169881) #169929
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…ilcalls" (#169881) This reverts commit 9bffb10. Fix: added assertions to the requirements of the test -------- Original commit message: In the Inliner pass, tailcalls are converted to calls in the inlined BasicBlock. If the tailcall is indirect, the `BR` is converted to `BLR`. These instructions require different BTI landing pads at their targets. As the targets of indirect tailcalls are unknown, inlining such blocks is unsound for BTI: they should be skipped instead.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
|
@llvm/pr-subscribers-bolt Author: Gergely Bálint (bgergely0) ChangesThis reverts commit 9bffb10. Fix: added assertions to the requirements of the test Original commit message: In the Inliner pass, tailcalls are converted to calls in the inlined These instructions require different BTI landing pads at their targets. As the targets of indirect tailcalls are unknown, inlining such blocks Full diff: https://github.com/llvm/llvm-project/pull/169929.diff 3 Files Affected:
diff --git a/bolt/lib/Passes/Inliner.cpp b/bolt/lib/Passes/Inliner.cpp
index 5a7d02a34b4d8..0740fcef9102b 100644
--- a/bolt/lib/Passes/Inliner.cpp
+++ b/bolt/lib/Passes/Inliner.cpp
@@ -491,6 +491,32 @@ bool Inliner::inlineCallsInFunction(BinaryFunction &Function) {
}
}
+ // AArch64 BTI:
+ // If the callee has an indirect tailcall (BR), we would transform it to
+ // an indirect call (BLR) in InlineCall. Because of this, we would have to
+ // update the BTI at the target of the tailcall. However, these targets
+ // are not known. Instead, we skip inlining blocks with indirect
+ // tailcalls.
+ auto HasIndirectTailCall = [&](const BinaryFunction &BF) -> bool {
+ for (const auto &BB : BF) {
+ for (const auto &II : BB) {
+ if (BC.MIB->isIndirectBranch(II) && BC.MIB->isTailCall(II)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+
+ if (BC.isAArch64() && BC.usesBTI() &&
+ HasIndirectTailCall(*TargetFunction)) {
+ ++InstIt;
+ LLVM_DEBUG(dbgs() << "BOLT-DEBUG: Skipping inlining block with tailcall"
+ << " in " << Function << " : " << BB->getName()
+ << " to keep BTIs consistent.\n");
+ continue;
+ }
+
LLVM_DEBUG(dbgs() << "BOLT-DEBUG: inlining call to " << *TargetFunction
<< " in " << Function << " : " << BB->getName()
<< ". Count: " << BB->getKnownExecutionCount()
diff --git a/bolt/test/AArch64/inline-bti-dbg.s b/bolt/test/AArch64/inline-bti-dbg.s
new file mode 100644
index 0000000000000..a0db4589d39ac
--- /dev/null
+++ b/bolt/test/AArch64/inline-bti-dbg.s
@@ -0,0 +1,40 @@
+# This test checks that for AArch64 binaries with BTI, we do not inline blocks with indirect tailcalls.
+# Same as inline-bti.s, but checks the debug output, and therefore requires assertions.
+
+# REQUIRES: system-linux, assertions
+
+# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o
+# RUN: %clang %cflags -O0 %t.o -o %t.exe -Wl,-q -Wl,-z,force-bti
+# RUN: llvm-bolt --inline-all %t.exe -o %t.bolt --debug 2>&1 | FileCheck %s
+
+# For BTI, we should not inline foo.
+# CHECK: BOLT-DEBUG: Skipping inlining block with tailcall in _Z3barP1A : .LBB01 to keep BTIs consistent.
+# CHECK-NOT: BOLT-INFO: inlined {{[0-9]+}} calls at {{[0-9]+}} call sites in {{[0-9]+}} iteration(s). Change in binary size: {{[0-9]+}} bytes.
+
+ .text
+ .globl _Z3fooP1A
+ .type _Z3fooP1A,@function
+_Z3fooP1A:
+ ldr x8, [x0]
+ ldr w0, [x8]
+ br x30
+ .size _Z3fooP1A, .-_Z3fooP1A
+
+ .globl _Z3barP1A
+ .type _Z3barP1A,@function
+_Z3barP1A:
+ stp x29, x30, [sp, #-16]!
+ mov x29, sp
+ bl _Z3fooP1A
+ mul w0, w0, w0
+ ldp x29, x30, [sp], #16
+ ret
+ .size _Z3barP1A, .-_Z3barP1A
+
+ .globl main
+ .p2align 2
+ .type main,@function
+main:
+ mov w0, wzr
+ ret
+ .size main, .-main
diff --git a/bolt/test/AArch64/inline-bti.s b/bolt/test/AArch64/inline-bti.s
new file mode 100644
index 0000000000000..62f6ea6f4b63a
--- /dev/null
+++ b/bolt/test/AArch64/inline-bti.s
@@ -0,0 +1,38 @@
+## This test checks that for AArch64 binaries with BTI, we do not inline blocks with indirect tailcalls.
+
+# REQUIRES: system-linux
+
+# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o
+# RUN: %clang %cflags -O0 %t.o -o %t.exe -Wl,-q -Wl,-z,force-bti
+# RUN: llvm-bolt --inline-all %t.exe -o %t.bolt | FileCheck %s
+
+# For BTI, we should not inline foo.
+# CHECK-NOT: BOLT-INFO: inlined {{[0-9]+}} calls at {{[0-9]+}} call sites in {{[0-9]+}} iteration(s). Change in binary size: {{[0-9]+}} bytes.
+
+ .text
+ .globl _Z3fooP1A
+ .type _Z3fooP1A,@function
+_Z3fooP1A:
+ ldr x8, [x0]
+ ldr w0, [x8]
+ br x30
+ .size _Z3fooP1A, .-_Z3fooP1A
+
+ .globl _Z3barP1A
+ .type _Z3barP1A,@function
+_Z3barP1A:
+ stp x29, x30, [sp, #-16]!
+ mov x29, sp
+ bl _Z3fooP1A
+ mul w0, w0, w0
+ ldp x29, x30, [sp], #16
+ ret
+ .size _Z3barP1A, .-_Z3barP1A
+
+ .globl main
+ .p2align 2
+ .type main,@function
+main:
+ mov w0, wzr
+ ret
+ .size main, .-main
|
paschalis-mpeis
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Could rewrite the commit message from "This reverts commit SHA1" to "This reapplies commit SHA2"
…ilcalls" (llvm#169881) (llvm#169929) This reapplies commit 5d6d743. Fix: added assertions to the requirements of the test -------- Original commit message: In the Inliner pass, tailcalls are converted to calls in the inlined BasicBlock. If the tailcall is indirect, the `BR` is converted to `BLR`. These instructions require different BTI landing pads at their targets. As the targets of indirect tailcalls are unknown, inlining such blocks is unsound for BTI: they should be skipped instead.

This reapplies commit 5d6d743.
Fix: added assertions to the requirements of the test
Original commit message:
In the Inliner pass, tailcalls are converted to calls in the inlined
BasicBlock. If the tailcall is indirect, the
BRis converted toBLR.These instructions require different BTI landing pads at their targets.
As the targets of indirect tailcalls are unknown, inlining such blocks
is unsound for BTI: they should be skipped instead.