[llvm] [BOLT] Handle internal calls in ValidateInternalCalls (PR #105736)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 22 14:36:02 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-bolt
Author: Maksim Panchenko (maksfb)
<details>
<summary>Changes</summary>
Move handling of all internal calls into the designated pass. Preserve NOPs and mark functions as non-simple on non-X86 platforms.
---
Full diff: https://github.com/llvm/llvm-project/pull/105736.diff
4 Files Affected:
- (modified) bolt/include/bolt/Core/BinaryFunction.h (+2)
- (modified) bolt/lib/Core/BinaryFunction.cpp (+4-16)
- (modified) bolt/lib/Passes/ValidateInternalCalls.cpp (+6-3)
- (added) bolt/test/AArch64/internal-call.s (+65)
``````````diff
diff --git a/bolt/include/bolt/Core/BinaryFunction.h b/bolt/include/bolt/Core/BinaryFunction.h
index 24c7db2f5d69ca..6ebbaf94754e87 100644
--- a/bolt/include/bolt/Core/BinaryFunction.h
+++ b/bolt/include/bolt/Core/BinaryFunction.h
@@ -1692,6 +1692,8 @@ class BinaryFunction {
void setPseudo(bool Pseudo) { IsPseudo = Pseudo; }
+ void setPreserveNops(bool Value) { PreserveNops = Value; }
+
BinaryFunction &setUsesGnuArgsSize(bool Uses = true) {
UsesGnuArgsSize = Uses;
return *this;
diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp
index af982fd60b17e7..e3037c868f6240 100644
--- a/bolt/lib/Core/BinaryFunction.cpp
+++ b/bolt/lib/Core/BinaryFunction.cpp
@@ -1339,22 +1339,10 @@ Error BinaryFunction::disassemble() {
BC.getBinaryFunctionContainingAddress(TargetAddress))
TargetFunc->setIgnored();
- if (IsCall && containsAddress(TargetAddress)) {
- if (TargetAddress == getAddress()) {
- // Recursive call.
- TargetSymbol = getSymbol();
- } else {
- if (BC.isX86()) {
- // Dangerous old-style x86 PIC code. We may need to freeze this
- // function, so preserve the function as is for now.
- PreserveNops = true;
- } else {
- BC.errs() << "BOLT-WARNING: internal call detected at 0x"
- << Twine::utohexstr(AbsoluteInstrAddr)
- << " in function " << *this << ". Skipping.\n";
- IsSimple = false;
- }
- }
+ if (IsCall && TargetAddress == getAddress()) {
+ // A recursive call. Call to internal blocks are handled by
+ // ValidateInternalCalls pass.
+ TargetSymbol = getSymbol();
}
if (!TargetSymbol) {
diff --git a/bolt/lib/Passes/ValidateInternalCalls.cpp b/bolt/lib/Passes/ValidateInternalCalls.cpp
index 88df2e5b59f389..bdab895b6ac2e8 100644
--- a/bolt/lib/Passes/ValidateInternalCalls.cpp
+++ b/bolt/lib/Passes/ValidateInternalCalls.cpp
@@ -302,9 +302,6 @@ bool ValidateInternalCalls::analyzeFunction(BinaryFunction &Function) const {
}
Error ValidateInternalCalls::runOnFunctions(BinaryContext &BC) {
- if (!BC.isX86())
- return Error::success();
-
// Look for functions that need validation. This should be pretty rare.
std::set<BinaryFunction *> NeedsValidation;
for (auto &BFI : BC.getBinaryFunctions()) {
@@ -312,14 +309,20 @@ Error ValidateInternalCalls::runOnFunctions(BinaryContext &BC) {
for (BinaryBasicBlock &BB : Function) {
for (MCInst &Inst : BB) {
if (getInternalCallTarget(Function, Inst)) {
+ BC.errs() << "BOLT-WARNING: internal call detected in function "
+ << Function << '\n';
NeedsValidation.insert(&Function);
Function.setSimple(false);
+ Function.setPreserveNops(true);
break;
}
}
}
}
+ if (!BC.isX86())
+ return Error::success();
+
// Skip validation for non-relocation mode
if (!BC.HasRelocations)
return Error::success();
diff --git a/bolt/test/AArch64/internal-call.s b/bolt/test/AArch64/internal-call.s
new file mode 100644
index 00000000000000..2fe05920869835
--- /dev/null
+++ b/bolt/test/AArch64/internal-call.s
@@ -0,0 +1,65 @@
+## Test that llvm-bolt detects internal calls and marks the containing function
+## as non-simple.
+
+# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o
+# RUN: %clang %cflags %t.o -o %t.exe -Wl,-q -static
+# RUN: llvm-bolt %t.exe -o /dev/null --print-all 2>&1 | FileCheck %s
+
+# CHECK: Binary Function "_start" after building cfg
+# CHECK: internal call detected in function _start
+# CHECK-NOT: Binary Function "_start" after validate-internal-calls
+
+ .text
+ .globl _start
+ .type _start, %function
+_start:
+ .cfi_startproc
+.LBB00:
+ mov x11, #0x1fff
+ cmp x1, x11
+ b.hi .Ltmp1
+
+.entry1:
+ movi v4.16b, #0x0
+ movi v5.16b, #0x0
+ subs x1, x1, #0x8
+ b.lo .Ltmp2
+
+.entry2:
+ ld1 { v2.2d, v3.2d }, [x0], #32
+ ld1 { v0.2d, v1.2d }, [x0], #32
+
+.Ltmp2:
+ uaddlp v4.4s, v4.8h
+ uaddlp v4.2d, v4.4s
+ mov x0, v4.d[0]
+ mov x1, v4.d[1]
+ add x0, x0, x1
+ ret x30
+
+.Ltmp1:
+ mov x8, x30
+
+.Lloop:
+ add x5, x0, x9
+ mov x1, #0xface
+ movi v4.16b, #0x0
+ movi v5.16b, #0x0
+ bl .entry2
+ add x4, x4, x0
+ mov x0, x5
+ sub x7, x7, x10
+ cmp x7, x11
+ b.hi .Lloop
+
+ mov x1, x7
+ bl .entry1
+ add x0, x4, x0
+ mov x30, x8
+ ret x30
+
+ .cfi_endproc
+.size _start, .-_start
+
+# Force relocation mode.
+ .reloc 0, R_AARCH64_NONE
``````````
</details>
https://github.com/llvm/llvm-project/pull/105736
More information about the llvm-commits
mailing list