[llvm] [BOLT] Not use hlt as split point when build the CFG (PR #150963)
Haibo Jiang via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 30 05:45:00 PDT 2025
https://github.com/Jianghibo updated https://github.com/llvm/llvm-project/pull/150963
>From 76b0ce75b818b548ba4c741086e163a6e51f6b0c Mon Sep 17 00:00:00 2001
From: jianghaibo <jianghaibo9 at huawei.com>
Date: Mon, 28 Jul 2025 22:43:43 +0800
Subject: [PATCH] [BOLT] Not use hlt as split point when build the CFG
For x86, the halt instruction is defined as a terminator instruction.
When building the CFG, the instruction sequence following the hlt
instruction is treated as an independent MBB. Since there is no
jump information, the predecessor of this MBB cannot be identified,
and it is considered an unreachable MBB that will be removed.
Using this fix, the instruction sequences before and after hlt are
refused to be placed in different blocks.
---
bolt/include/bolt/Core/MCPlusBuilder.h | 3 +++
bolt/lib/Core/MCPlusBuilder.cpp | 5 +++--
bolt/lib/Target/X86/X86MCPlusBuilder.cpp | 4 ++++
bolt/test/X86/cfg_build_hlt.s | 21 +++++++++++++++++++++
4 files changed, 31 insertions(+), 2 deletions(-)
create mode 100644 bolt/test/X86/cfg_build_hlt.s
diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h b/bolt/include/bolt/Core/MCPlusBuilder.h
index f902a8c43cd1d..ac9e8e7297534 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -740,6 +740,9 @@ class MCPlusBuilder {
return false;
}
+ /// Return true if the hlt instruction under the x86, otherwise, default to false.
+ virtual bool isX86HLT(const MCInst &Inst) const { return false; }
+
/// Return the width, in bytes, of the memory access performed by \p Inst, if
/// this is a pop instruction. Return zero otherwise.
virtual int getPopSize(const MCInst &Inst) const {
diff --git a/bolt/lib/Core/MCPlusBuilder.cpp b/bolt/lib/Core/MCPlusBuilder.cpp
index fa8f4d1df308b..6740190e6cfe4 100644
--- a/bolt/lib/Core/MCPlusBuilder.cpp
+++ b/bolt/lib/Core/MCPlusBuilder.cpp
@@ -132,8 +132,9 @@ bool MCPlusBuilder::equals(const MCSpecifierExpr &A, const MCSpecifierExpr &B,
}
bool MCPlusBuilder::isTerminator(const MCInst &Inst) const {
- return Analysis->isTerminator(Inst) ||
- (opts::TerminalTrap && Info->get(Inst.getOpcode()).isTrap());
+ return (opts::TerminalTrap && Info->get(Inst.getOpcode()).isTrap()) ||
+ Analysis->isTerminator(Inst) ? !isX86HLT(Inst)
+ : false;
}
void MCPlusBuilder::setTailCall(MCInst &Inst) const {
diff --git a/bolt/lib/Target/X86/X86MCPlusBuilder.cpp b/bolt/lib/Target/X86/X86MCPlusBuilder.cpp
index a60c1a6bf156e..1842509dcc5e0 100644
--- a/bolt/lib/Target/X86/X86MCPlusBuilder.cpp
+++ b/bolt/lib/Target/X86/X86MCPlusBuilder.cpp
@@ -223,6 +223,10 @@ class X86MCPlusBuilder : public MCPlusBuilder {
return Inst.getOpcode() == X86::ENDBR32 || Inst.getOpcode() == X86::ENDBR64;
}
+ bool isX86HLT(const MCInst &Inst) const override {
+ return Inst.getOpcode() == X86::HLT;
+ }
+
int getPopSize(const MCInst &Inst) const override {
switch (Inst.getOpcode()) {
case X86::POP16r:
diff --git a/bolt/test/X86/cfg_build_hlt.s b/bolt/test/X86/cfg_build_hlt.s
new file mode 100644
index 0000000000000..263fae4f1fa76
--- /dev/null
+++ b/bolt/test/X86/cfg_build_hlt.s
@@ -0,0 +1,21 @@
+## Check CFG for halt instruction
+
+# RUN: %clang %cflags %s -static -o %t.exe -nostdlib
+# RUN: llvm-bolt %t.exe --print-cfg -o %t 2>&1 | FileCheck %s --check-prefix=CHECK-CFG
+# RUN: llvm-objdump -d %t --print-imm-hex | FileCheck %s --check-prefix=CHECK-BIN
+
+# CHECK-CFG: BB Count : 1
+# CHECK-BIN: <main>:
+# CHECK-BIN-NEXT: 55 pushq %rbp
+# CHECK-BIN-NEXT: 48 89 e5 movq %rsp, %rbp
+# CHECK-BIN-NEXT: f4 hlt
+# CHECK-BIN-NEXT: c3 retq
+
+.global main
+ .type main, %function
+main:
+ pushq %rbp
+ movq %rsp, %rbp
+ hlt
+ retq
+.size main, .-main
More information about the llvm-commits
mailing list