[llvm] [BOLT][RISCV] Add RISCV tests for external branch target validation (PR #223991)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 16 06:22:26 PDT 2026
https://github.com/Thrrreeee updated https://github.com/llvm/llvm-project/pull/223991
>From 58bd9827a15bf9af7c86525e91bffe4c7fb5a3c3 Mon Sep 17 00:00:00 2001
From: shijinrui <shijinrui at bytedance.com>
Date: Wed, 16 Sep 2026 20:12:23 +0800
Subject: [PATCH 1/3] [BOLT][RISCV] add RISCV test for ExternalBranch
validation
---
.../RISCV/constant-island-branch-rescan.s | 43 +++++++++++++++
.../RISCV/validate-multiple-branch-targets.s | 55 +++++++++++++++++++
2 files changed, 98 insertions(+)
create mode 100644 bolt/test/RISCV/constant-island-branch-rescan.s
create mode 100644 bolt/test/RISCV/validate-multiple-branch-targets.s
diff --git a/bolt/test/RISCV/constant-island-branch-rescan.s b/bolt/test/RISCV/constant-island-branch-rescan.s
new file mode 100644
index 0000000000000..f8d0694306710
--- /dev/null
+++ b/bolt/test/RISCV/constant-island-branch-rescan.s
@@ -0,0 +1,43 @@
+## Reject a data-island target again when ignoring the source rescans its
+## references. The data word is an instruction encoding, as in assembly that
+## emits instructions as data; its mapping symbol still identifies data.
+## Both the source and target must retain their original addresses and bytes.
+
+# RUN: llvm-mc -triple=riscv64 -filetype=obj %s -o %t.o
+# RUN: ld.lld --emit-relocs -Ttext=0x10000 %t.o -o %t.exe
+# RUN: llvm-objcopy --dump-section=.text=%t.original.text %t.exe
+# RUN: llvm-bolt %t.exe -o %t.bolt 2>&1 | FileCheck %s --check-prefix=DIAG
+# RUN: llvm-nm --defined-only %t.bolt | FileCheck %s --check-prefix=ADDR --implicit-check-not=__ENTRY_
+# RUN: llvm-objcopy --dump-section=.bolt.org.text=%t.output.text %t.bolt
+# RUN: cmp %t.original.text %t.output.text
+# RUN: llvm-bolt %t.exe -o %t.skip.bolt --skip-funcs=_start 2>&1 | FileCheck %s --check-prefix=DIAG
+# RUN: llvm-nm --defined-only %t.skip.bolt | FileCheck %s --check-prefix=ADDR --implicit-check-not=__ENTRY_
+# RUN: llvm-objcopy --dump-section=.bolt.org.text=%t.skip.text %t.skip.bolt
+# RUN: cmp %t.original.text %t.skip.text
+
+## The same invalid reference must not be diagnosed repeatedly during rescans.
+# DIAG: BOLT-WARNING: ignoring entry point at address 0x1000c in constant island of function target
+# DIAG-NOT: ignoring entry point
+# DIAG-NOT: BOLT-ERROR
+# ADDR-DAG: 0000000000010000 T _start
+# ADDR-DAG: 0000000000010008 T target
+
+ .text
+ .option norvc
+ .globl _start
+ .type _start, at function
+_start:
+ beq t0, t1, .Ldata
+ ret
+ .size _start, .-_start
+
+ .globl target
+ .type target, at function
+target:
+ nop
+.Ldata:
+ .word 0xcd027057
+ ret
+ .size target, .-target
+
+ .reloc 0, R_RISCV_NONE
diff --git a/bolt/test/RISCV/validate-multiple-branch-targets.s b/bolt/test/RISCV/validate-multiple-branch-targets.s
new file mode 100644
index 0000000000000..e5a115ce0e958
--- /dev/null
+++ b/bolt/test/RISCV/validate-multiple-branch-targets.s
@@ -0,0 +1,55 @@
+## Reject every invalid target from a source, including an instruction-middle
+## target after a data-island target. Deferring setIgnored() until validation
+## completes must preserve the instruction boundaries needed for later checks.
+
+# RUN: llvm-mc -triple=riscv64 -filetype=obj %s -o %t.o
+# RUN: ld.lld --emit-relocs -Ttext=0x10000 %t.o -o %t.exe
+# RUN: llvm-objcopy --dump-section=.text=%t.original.text %t.exe
+# RUN: llvm-bolt %t.exe -o %t.bolt 2>&1 | FileCheck %s --check-prefix=DIAG
+# RUN: llvm-nm --defined-only %t.bolt | FileCheck %s --check-prefix=ADDR --implicit-check-not=__ENTRY_
+# RUN: llvm-objcopy --dump-section=.bolt.org.text=%t.output.text %t.bolt
+# RUN: cmp %t.original.text %t.output.text
+# RUN: llvm-bolt %t.exe -o %t.skip.bolt --skip-funcs=_start 2>&1 | FileCheck %s --check-prefix=DIAG
+# RUN: llvm-nm --defined-only %t.skip.bolt | FileCheck %s --check-prefix=ADDR --implicit-check-not=__ENTRY_
+# RUN: llvm-objcopy --dump-section=.bolt.org.text=%t.skip.text %t.skip.bolt
+# RUN: cmp %t.original.text %t.skip.text
+
+# DIAG: BOLT-WARNING: corrupted control flow detected in function _start: an external branch/call targets an invalid instruction in function data_target at address 0x10004; ignoring both functions
+# DIAG-NEXT: BOLT-WARNING: ignoring entry point at address 0x10004 in constant island of function data_target
+# DIAG-NEXT: BOLT-WARNING: corrupted control flow detected in function _start: an external branch/call targets an invalid instruction in function instruction_target at address 0x1000e; ignoring both functions
+# DIAG-NOT: corrupted control flow detected
+# DIAG-NOT: ignoring entry point
+# DIAG-NOT: BOLT-ERROR
+# ADDR-DAG: 0000000000010000 T data_target
+# ADDR-DAG: 000000000001000c T instruction_target
+# ADDR-DAG: 0000000000010014 T _start
+
+ .text
+ .option norvc
+## Targets precede the source so their instruction boundaries are available
+## when the explicit --skip-funcs run scans the source's external references.
+ .globl data_target
+ .type data_target, at function
+data_target:
+ nop
+.Ldata:
+ .word 0xcd027057
+ ret
+ .size data_target, .-data_target
+
+ .globl instruction_target
+ .type instruction_target, at function
+instruction_target:
+ addi a0, a0, 1
+ ret
+ .size instruction_target, .-instruction_target
+
+ .globl _start
+ .type _start, at function
+_start:
+ beq a0, a1, .Ldata
+ beq a2, a3, instruction_target + 2
+ ret
+ .size _start, .-_start
+
+ .reloc 0, R_RISCV_NONE
>From 2cee9fb716a7f41f4c1f8bf7c0d3db9e9d7f94db Mon Sep 17 00:00:00 2001
From: shijinrui <shijinrui at bytedance.com>
Date: Wed, 16 Sep 2026 21:00:44 +0800
Subject: [PATCH 2/3] clean additional code
---
bolt/test/RISCV/constant-island-branch-rescan.s | 14 +++-----------
.../RISCV/validate-multiple-branch-targets.s | 16 +++-------------
2 files changed, 6 insertions(+), 24 deletions(-)
diff --git a/bolt/test/RISCV/constant-island-branch-rescan.s b/bolt/test/RISCV/constant-island-branch-rescan.s
index f8d0694306710..0edb6bfa84d63 100644
--- a/bolt/test/RISCV/constant-island-branch-rescan.s
+++ b/bolt/test/RISCV/constant-island-branch-rescan.s
@@ -1,38 +1,30 @@
## Reject a data-island target again when ignoring the source rescans its
## references. The data word is an instruction encoding, as in assembly that
## emits instructions as data; its mapping symbol still identifies data.
-## Both the source and target must retain their original addresses and bytes.
+## Both the source and target must retain their original addresses.
# RUN: llvm-mc -triple=riscv64 -filetype=obj %s -o %t.o
# RUN: ld.lld --emit-relocs -Ttext=0x10000 %t.o -o %t.exe
-# RUN: llvm-objcopy --dump-section=.text=%t.original.text %t.exe
# RUN: llvm-bolt %t.exe -o %t.bolt 2>&1 | FileCheck %s --check-prefix=DIAG
# RUN: llvm-nm --defined-only %t.bolt | FileCheck %s --check-prefix=ADDR --implicit-check-not=__ENTRY_
-# RUN: llvm-objcopy --dump-section=.bolt.org.text=%t.output.text %t.bolt
-# RUN: cmp %t.original.text %t.output.text
# RUN: llvm-bolt %t.exe -o %t.skip.bolt --skip-funcs=_start 2>&1 | FileCheck %s --check-prefix=DIAG
# RUN: llvm-nm --defined-only %t.skip.bolt | FileCheck %s --check-prefix=ADDR --implicit-check-not=__ENTRY_
-# RUN: llvm-objcopy --dump-section=.bolt.org.text=%t.skip.text %t.skip.bolt
-# RUN: cmp %t.original.text %t.skip.text
## The same invalid reference must not be diagnosed repeatedly during rescans.
# DIAG: BOLT-WARNING: ignoring entry point at address 0x1000c in constant island of function target
# DIAG-NOT: ignoring entry point
-# DIAG-NOT: BOLT-ERROR
# ADDR-DAG: 0000000000010000 T _start
# ADDR-DAG: 0000000000010008 T target
- .text
- .option norvc
.globl _start
- .type _start, at function
+ .type _start, @function
_start:
beq t0, t1, .Ldata
ret
.size _start, .-_start
.globl target
- .type target, at function
+ .type target, @function
target:
nop
.Ldata:
diff --git a/bolt/test/RISCV/validate-multiple-branch-targets.s b/bolt/test/RISCV/validate-multiple-branch-targets.s
index e5a115ce0e958..7b12a1f5b3faa 100644
--- a/bolt/test/RISCV/validate-multiple-branch-targets.s
+++ b/bolt/test/RISCV/validate-multiple-branch-targets.s
@@ -4,32 +4,24 @@
# RUN: llvm-mc -triple=riscv64 -filetype=obj %s -o %t.o
# RUN: ld.lld --emit-relocs -Ttext=0x10000 %t.o -o %t.exe
-# RUN: llvm-objcopy --dump-section=.text=%t.original.text %t.exe
# RUN: llvm-bolt %t.exe -o %t.bolt 2>&1 | FileCheck %s --check-prefix=DIAG
# RUN: llvm-nm --defined-only %t.bolt | FileCheck %s --check-prefix=ADDR --implicit-check-not=__ENTRY_
-# RUN: llvm-objcopy --dump-section=.bolt.org.text=%t.output.text %t.bolt
-# RUN: cmp %t.original.text %t.output.text
# RUN: llvm-bolt %t.exe -o %t.skip.bolt --skip-funcs=_start 2>&1 | FileCheck %s --check-prefix=DIAG
# RUN: llvm-nm --defined-only %t.skip.bolt | FileCheck %s --check-prefix=ADDR --implicit-check-not=__ENTRY_
-# RUN: llvm-objcopy --dump-section=.bolt.org.text=%t.skip.text %t.skip.bolt
-# RUN: cmp %t.original.text %t.skip.text
# DIAG: BOLT-WARNING: corrupted control flow detected in function _start: an external branch/call targets an invalid instruction in function data_target at address 0x10004; ignoring both functions
# DIAG-NEXT: BOLT-WARNING: ignoring entry point at address 0x10004 in constant island of function data_target
# DIAG-NEXT: BOLT-WARNING: corrupted control flow detected in function _start: an external branch/call targets an invalid instruction in function instruction_target at address 0x1000e; ignoring both functions
# DIAG-NOT: corrupted control flow detected
# DIAG-NOT: ignoring entry point
-# DIAG-NOT: BOLT-ERROR
# ADDR-DAG: 0000000000010000 T data_target
# ADDR-DAG: 000000000001000c T instruction_target
# ADDR-DAG: 0000000000010014 T _start
- .text
- .option norvc
## Targets precede the source so their instruction boundaries are available
## when the explicit --skip-funcs run scans the source's external references.
.globl data_target
- .type data_target, at function
+ .type data_target, @function
data_target:
nop
.Ldata:
@@ -38,18 +30,16 @@ data_target:
.size data_target, .-data_target
.globl instruction_target
- .type instruction_target, at function
+ .type instruction_target, @function
instruction_target:
addi a0, a0, 1
ret
.size instruction_target, .-instruction_target
.globl _start
- .type _start, at function
+ .type _start, @function
_start:
beq a0, a1, .Ldata
beq a2, a3, instruction_target + 2
ret
.size _start, .-_start
-
- .reloc 0, R_RISCV_NONE
>From 2f83a1ef5380c65433f70dfa895cd85c1bb025d9 Mon Sep 17 00:00:00 2001
From: shijinrui <shijinrui at bytedance.com>
Date: Wed, 16 Sep 2026 21:22:06 +0800
Subject: [PATCH 3/3] add .text
---
bolt/test/RISCV/constant-island-branch-rescan.s | 1 +
bolt/test/RISCV/validate-multiple-branch-targets.s | 1 +
2 files changed, 2 insertions(+)
diff --git a/bolt/test/RISCV/constant-island-branch-rescan.s b/bolt/test/RISCV/constant-island-branch-rescan.s
index 0edb6bfa84d63..03eecebcc7f10 100644
--- a/bolt/test/RISCV/constant-island-branch-rescan.s
+++ b/bolt/test/RISCV/constant-island-branch-rescan.s
@@ -16,6 +16,7 @@
# ADDR-DAG: 0000000000010000 T _start
# ADDR-DAG: 0000000000010008 T target
+ .text
.globl _start
.type _start, @function
_start:
diff --git a/bolt/test/RISCV/validate-multiple-branch-targets.s b/bolt/test/RISCV/validate-multiple-branch-targets.s
index 7b12a1f5b3faa..6a7f1866d1ce5 100644
--- a/bolt/test/RISCV/validate-multiple-branch-targets.s
+++ b/bolt/test/RISCV/validate-multiple-branch-targets.s
@@ -18,6 +18,7 @@
# ADDR-DAG: 000000000001000c T instruction_target
# ADDR-DAG: 0000000000010014 T _start
+ .text
## Targets precede the source so their instruction boundaries are available
## when the explicit --skip-funcs run scans the source's external references.
.globl data_target
More information about the llvm-commits
mailing list