2618 Commits

Author SHA1 Message Date
YafetBeyene
fda24dbc16
[BOLT] Add dump-dot-func option for selective function CFG dumping (#153007)
## Change:
* Added `--dump-dot-func` command-line option that allows users to dump
CFGs only for specific functions instead of dumping all functions (the
current only available option being `--dump-dot-all`)

## Usage:
* Users can now specify function names or regex patterns (e.g.,
`--dump-dot-func=main,helper` or `--dump-dot-func="init.*`") to generate
.dot files only for functions of interest
* Aims to save time when analysing specific functions in large binaries
(e.g., only dumping graphs for performance-critical functions identified
through profiling) and we can now avoid reduce output clutter from
generating thousands of unnecessary .dot files when analysing large
binaries

## Testing
The introduced test `dump-dot-func.test` confirms the new option does
the following:

- [x] 1. `dump-dot-func` can correctly filter a specified functions
- [x] 2. Can achieve the above with regexes
- [x] 3. Can do 1. with a list of functions
- [x] No option specified creates no dot files
- [x] Passing in a non-existent function generates no dumping messages
- [x] `dump-dot-all` continues to work as expected
2025-08-22 10:51:09 +01:00
YongKang Zhu
5c4f506cca
[BOLT] Validate extra entry point by querying data marker symbols (#154611)
Look up marker symbols and decide whether candidate is really
extra entry point in `adjustFunctionBoundaries()`.
2025-08-20 14:18:56 -07:00
Maksim Panchenko
0d9b9d1eef
[BOLT] Keep X86 HLT instruction as a terminator in user mode (#154402)
This is a follow-up to #150963. X86 HLT instruction may appear in the
user-level code, in which case we should treat it as a terminator.
Handle it as a non-terminator in the Linux kernel mode.
2025-08-19 14:41:13 -07:00
Fangrui Song
34c7b7ccae MCSymbol: Remove setUndefined
The name is misleading, as setting Fragment to nullptr does not
necessarily make it undefined - common and equated symbols have
a nullptr fragment as well.
2025-08-17 15:57:27 -07:00
Haibo Jiang
21a5729b87
[BOLT] Do not use HLT as split point when build the CFG (#150963)
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.
2025-08-15 14:35:13 -07:00
Paschalis Mpeis
6ebb8901cc
[BOLT][AArch64] Refuse to run FrameOptimizer pass (#152309)
FrameOptimizer pass runs by default on all targets, however, it defaults
to --frame-opt=none. This patch prevents the pass from running on
non-x86 targets when any other value (hot, full) is specified.
2025-08-08 11:30:42 +03:00
Rafael Auler
47f54e4992
Revert "[BOLT][NFC] Register profiled functions once (#150622)" (#152597)
In perf2bolt, we are observing sporadic crashes in the recently added
registerProfiledFunctions from #150622. Addresses provided by the
hardware (from LBR) might be -1, which clashes with what LLVM uses in
DenseSet as empty tombstones records. This causes DenseSet to assert
with "can't insert empty tombstone into map" when ingesting this
data. Revert this change for now to unbreak perf2bolt.
2025-08-07 15:28:22 -07:00
Anatoly Trosinenko
4da745a0f4
[BOLT] Fix unit test failures with LLVM_LINK_LLVM_DYLIB=ON (#152190)
When LLVM_LINK_LLVM_DYLIB is ON, `check-bolt` target reports unit test
failures:

    BOLT-Unit :: Core/./CoreTests/failed_to_discover_tests_from_gtest
    BOLT-Unit :: Profile/./ProfileTests/failed_to_discover_tests_from_gtest

The reason is that when llvm-lit runs a unit-test executable:

    /path/to/CoreTests --gtest_list_tests '--gtest_filter=-*DISABLED_*'

an assertion is triggered with the following message:

    LLVM ERROR: Option 'default' already exists!

This assertion triggers when the initializer of defaultListDAGScheduler
defined at SelectionDAGISel.cpp:219 is called as a statically-linked
function after already being called during the initialization of
libLLVM.

The issue can be traced down to LLVMTestingSupport library which depends
on libLLVM as neither COMPONENT_LIB nor DISABLE_LLVM_LINK_LLVM_DYLIB is
specified in a call to `add_llvm_library(LLVMTestingSupport ...)`.

Specifying DISABLE_LLVM_LINK_LLVM_DYLIB for LLVMTestingSupport makes
Clang unit test fail and COMPONENT_LIB is probably inappropriate for a
testing-specific library, thus as a workaround, added Error.cpp source
from LLVMTestingSupport directly to the list of source files of
CoreTests target (as it depends on
`llvm::detail::TakeError(llvm::Error)`) and removed LLVMTestingSupport
from the list of dependencies of ProfileTests.
2025-08-07 11:27:15 +03:00
Dmitry Vasilyev
c233deb794
[BOLT] Use llvm-nm by default on Windows (#151805)
Use `llvm-nm` by default instead of `nm` in case of Windows host.
2025-08-05 11:33:26 +04:00
Kazu Hirata
b6cfa023b4
[BOLT] Use std::optional::value_or (NFC) (#151628) 2025-08-01 07:01:58 -07:00
Dmitry Vasilyev
c00df536e3
[BOLT] Fixed cmdline-args.test to work on Windows (#151209)
Added regex to ignore `.exe` in the executable name. 
Ignored OS-dependent message "No such file or directory".
2025-07-31 18:25:39 +04:00
Dmitry Vasilyev
c39b1aedd1
[BOLT] Fixed calling clang++ in tests on Windows (#151193)
`RUN: %clang++ ` tried to execute `clang.exe++` on Windows. Use `%clangxx` instead.
2025-07-31 18:25:09 +04:00
Dmitry Vasilyev
497d177375
[BOLT] Allow to compile with MSVC (#151189)
This change is necessary to build BOLT with MSVC on Windows.
2025-07-30 13:57:11 +04:00
Maksim Panchenko
1e0edb072a
[BOLT][AArch64] Compensate for missing code markers (#151060)
Code written in assembly can have missing code markers. In BOLT, we can
compensate by recognizing that a function entry point should start a
code sequence.

Seen such code in lua jit library.
2025-07-29 12:01:06 -07:00
Amir Ayupov
1b657c6d6b
[BOLT][NFC] Register profiled functions once (#150622)
While registering profiled functions, only handle each address once.
Speeds up `DataAggregator::preprocessProfile`.

Test Plan:
For intermediate size pre-aggregated profile (10MB), reduces parsing
time from ~0.41s down to ~0.16s.
2025-07-28 13:29:55 +02:00
Aiden Grossman
a7516dd38c
[BOLT] Remove Uses of %T From Lit Tests (#150716)
This patch removes all uses of %T from lit tests within bolt/. %T has
been listed as deprecated for ~7 years and should not be used given it
is not unique per test which means tests that use the same filenames can
race.
2025-07-26 10:13:12 -07:00
Amir Ayupov
a850912de1
[BOLT] Require CFG in BAT mode (#150488)
`getFallthroughsInTrace` requires CFG for functions not covered by BAT,
even in BAT/fdata mode. BAT-covered functions go through special
handling in fdata (`BAT->getFallthroughsInTrace`) and YAML
(`DataAggregator::writeBATYAML`) modes.

Since all modes (BAT/no-BAT, YAML/fdata) now need disassembly/CFG
construction:
- drop special BAT/fdata handling that omitted disassembly/CFG in
  `RewriteInstance::run`, enabling *CFG for all non-BAT functions*,
- switch `getFallthroughsInTrace` to check if a function has CFG,
- which *allows emitting profile for non-simple functions* in all modes.

Previously, traces in non-simple functions were reported as invalid/
mismatching disassembled function contents. This change reduces the
number of such invalid traces and increases the number of profiled
functions. These functions may participate in function reordering via
call graph profile.

Test Plan: updated unclaimed-jt-entries.s
2025-07-25 13:54:37 +02:00
Maksim Panchenko
d5d94ba8bc
[BOLT] More refactoring of PHDR handling. NFC (#148932)
Replace ad-hoc adjustment of the program header count with info from the
new segment list.
2025-07-24 11:47:27 -07:00
Paschalis Mpeis
d8adb57b44
[BOLT][NFC] Update nfc-check-setup.py guidance (#146659) 2025-07-22 09:47:40 +03:00
Paschalis Mpeis
597f3c1bd5
[BOLT] Improve exception handling in NFC-Mode (#146513)
This patch introduces the following improvements:
- Catch an exception when the CMakeCache.txt is not present
- Bail out gracefully when llvm-bolt did not build successfully the
  current or previous revision.
- Always do a `--switch-back` even if building the old revision failed
2025-07-22 09:18:30 +03:00
Paschalis Mpeis
3408f7b42f
[BOLT] Guard llvm-bolt-wrapper logic of NFC-Mode behind a flag (#146209)
Buildbot (`BOLTBuilder`) no longer relies on a wrapper script to run
tests. This
patch guards the wrapper logic under a flag that is disabled by default.
This
it allows to:
- Eliminate the need for special handling in some tests.
- Fix the issue of a wrapper loop (described below)
- Simplify the NFC-Mode setup.

**Background:**
Previously, tests ran unconditionally, which also compiled any missing
utilities
and the unit tests.

The `nfc-check-setup.py` created:
- `llvm-bolt.new`, renamed from the current compilation
- `llvm-bolt.old`, built from the previous SHA
- `llvm-bolt`: a python wrapper pointing to `llvm-bolt.new`

Current behaviour and wrapper issue:
As before, the old/new binaries identify whether a patch affects BOLT.
If so,
`ninja check-bolt` builds missing dependencies and run tests,
overwriting the
`llvm-bolt` wrapper with a binary.

However, if Ninja reports:
```
ninja: no work to do.
```

the wrapper remains in place. If the next commit also does no work,
`nfc-check-setup.py` renames the existing wrapper to `llvm-bolt.new`,
causing an
infinite loop.

Allowing to disable the wrapper logic prevents this scenario and
simplifies the flow.


**Test plan:**

Creates llvm-bolt.new and llvm-bolt.old and stays on previous revision:
```
./nfc-check-setup.py build
```

Creates llvm-bolt.new and llvm-bolt.old and returns on current revision:
```
./nfc-check-setup.py build --switch-back
```

Creates llvm-bolt.new and llvm-bolt.old, returns on current revision,
and
creates a wrapper:
```
./nfc-check-setup.py build --switch-back --create-wrapper
```

Creates llvm-bolt.new and llvm-bolt.old, and passes an invalid argument
to the
wrapper:
```
./nfc-check-setup.py build --switch-back --create-wrapper --random-arg
```
2025-07-22 09:04:00 +03:00
Amir Ayupov
0d5325bb20
[BOLT] Directly use call count in buildCallGraph (#134966)
In call graph construction, call block count is used for call graph edge
weight. Change that to use call count directly if it's available, 
falling back to block count if not.

Test Plan:
This change together with disabling `fix-block-counts` improves profile
quality metrics, e.g. for large binaries and sampled LBR profiles:

`br_inst_retired.near_taken:uppp` trigger event
- Ads1: 
  - Profiled functions 58096
  - CFG imbalance 2.63% -> 2.45%
  - CG imbalance 8.23% -> 7.44%

- Ads2:
  - Profiled functions 54358
  - CFG imbalance 3.12% -> 2.77%
  - CG imbalance 8.22% -> 7.06%

- uwsgi:
  - Profiled functions 78103
  - CFG imbalance 4.42% -> 4.03%
  - CG imbalance 100.00% -> 100.00%

`cycles:u` trigger event:
- web: 
  - Profiled functions 31306
  - CG flow imbalance: 31.16% -> 20.29%
  - CFG flow imbalance: 7.04% -> 6.44%
2025-07-14 14:28:52 -07:00
YongKang Zhu
dadaa7941d
[BOLT][instr] Add optional arguments to __bolt_instr_data_dump() (#148700)
`__bolt_instr_data_dump()` will find instrumented binary name by
iterating through entries under directory `/proc/self/map_files`,
and then open the binary and memory map it onto heap in order
to locate `.bolt.instr.tables` section to read the descriptions.
If binary name is already known and/or binary is already opened
as memory mapped, we can pass binary name and/or memory
buffer directly to `__bolt_instr_data_dump()` to save some work.
2025-07-14 13:06:16 -07:00
Peter Waller
81ad8e6345
[BOLT] Force frame pointers off for runtimes (#148009)
Distributions are making the choice to turn frame pointers on by
default. Nixpkgs recently turned them on, and the method they use to do
so implies that everything is built with them on by default.

https://github.com/NixOS/nixpkgs/pull/399014

Assuming that a well behaved distribution doing this puts
`-fno-omit-frame-pointer` at the beginning of the compiler invocation,
we can still re-enable omission by supplying `-fomit-frame-pointer`
during compilation.

This fixes some segfaults from stack corruption in binaries rewritten by
bolt with `llvm-bolt -instrument`.

See also: #147569
Fixes: #148595
2025-07-14 11:03:35 +01:00
YongKang Zhu
e088334432
[BOLT][NFC] Add const qualifier to certain pointers to read-only objects (#148543) 2025-07-13 19:17:20 -07:00
Amir Ayupov
00311cf604
[BOLT] Impute missing trace fall-through (#145258) 2025-07-12 12:25:58 -07:00
Asher Dobrescu
c8c0e90233
[BOLT] Ensure remember and restore CFIs are in the same list (#144348)
In `addCFIInstruction`, we split the CFI information
between `CFIInstrMapType CIEFrameInstructions` and `CFIInstrMapType
FrameInstructions`. In some cases we can end up with the remember CFI in
`CIEFrameInstructions` and the restore CFI in `FrameInstructions`. This
patch adds a check to make sure we do not split remember and restore
states and fixes https://github.com/llvm/llvm-project/issues/133501.
2025-07-10 15:48:57 +01:00
Fangrui Song
dcf485609c
MC: Centralize X86 PC-relative fixup adjustment in MCAssembler
Move the X86 PC-relative fixup adjustment from
X86MCCodeEmitter::emitImmediate to MCAssembler, leveraging a generalized
evaluateFixup. This saves a MCBinaryExpr. For `call foo`, the fixup
expression is now `foo` instead of `foo-4`. There is no change in
generated relocations.

In bolt/lib/Target/X86/X86MCPlusBuilder.cpp, createRelocation needs to
decrease the addend.

Both max-rss and instructions:u show a minor decrease.
https://llvm-compile-time-tracker.com/compare.php?from=ea600576a6f94d6f28925c4b99962cc26b463c29&to=016e8fd4ddf851e5555f606c6394241d68f1a7bb&stat=max-rss&linkStats=on

Next: Update targets that use FKF_IsAlignedDownTo32Bits to define
`evaluateFixup` and remove FKF_IsAlignedDownTo32Bits from the generic
code.

Pull Request: https://github.com/llvm/llvm-project/pull/147113
2025-07-08 09:22:30 -07:00
Amir Ayupov
46e3ec0244
[BOLT][NFCI] Report perf script time (#147232)
Leverage `sys::ProcessStatistics` to report the run time and memory
usage of perf script processes launched when reading perf data.
The reporting is enabled in debug mode with `-debug-only=aggregator`.

Switch buildid-list command to non-waiting `launchPerfProcess` to get
its runtime as well, unifying it with the rest of perf script processes.

Test Plan: NFC
2025-07-07 06:05:48 -07:00
Fangrui Song
244e053b6c MC: Remove llvm/MC/MCFixupKindInfo.h
The file used to define `MCFixupKindInfo`, a simple structure,
which is now in MCAsmBackend.h.
2025-07-05 11:24:11 -07:00
Fangrui Song
5b7f1c17d9 BOLT: Replace deprecated MCFixupKindInfo::FKF_IsPCRel with MCFixup::isPCRel
MCFixup::PCRel is now set at creation and the MCFixupKindInfo::FKF_IsPCRel flag
is no longer set.
2025-07-04 17:33:20 -07:00
Fangrui Song
2bfc488d34 X86MCCodeEmitter: Remove unneeded MCFixupKindInfo::FKF_IsPCRel 2025-07-04 16:30:07 -07:00
Maksim Panchenko
218fd69261
[BOLT] Decouple new segment creation from PHDR rewrite. NFCI (#146111)
Refactor handling of PHDR table rewrite to make modifications easier.
2025-07-02 11:22:12 -07:00
Maksim Panchenko
ad7d675991
[BOLT] Refactor mapCodeSections(). NFC (#146434)
Factor out non-relocation specific code into a separate function.
2025-06-30 17:09:41 -07:00
Maksim Panchenko
fb24b4d46a
[BOLT] Push code to higher addresses under options (#146180)
When --hot-functions-at-end is used in combination with --use-old-text,
allocate code at the highest possible addresses withing old .text.

This feature is mostly useful for HHVM, where it is beneficial to have
hot static code placed as close as possible to jitted code.
2025-06-28 13:53:56 -07:00
Fangrui Song
28d4cc6d7b MC: Reduce MCSymbolRefExpr::VK_None uses 2025-06-27 21:55:36 -07:00
Fangrui Song
109b7d965c MC: Remove unneeded VK_None argument to MCSymbolRefExpr::create calls
The MCSymbolRefExpr::create overload with the specifier parameter is
discouraged and being phased out. Expressions with relocation specifiers
should use MCSpecifierExpr instead.
2025-06-27 21:22:46 -07:00
Maksim Panchenko
54a7d53227 [BOLT] Fix program-header.test 2025-06-27 19:51:51 -07:00
Amir Ayupov
17328f36f6
[BOLT][test] Fix NFC mismatches in perf2bolt tests (#146148)
zero-density.s causes spurious NFC mismatches, e.g.
https://lab.llvm.org/buildbot/#/builders/92/builds/21380

This is caused by NFC script wrapping llvm-bolt binary only, so that
perf2bolt invocations are replaced by `llvm-bolt --agregate-only` to
achieve perf2bolt behavior. Add `show-density` to the list of flags
wrapping perf2bolt calls to avoid similar issues in the future.

Test Plan:
```
$ bolt/utils/nfc-check-setup.py --switch-back
$ bin/llvm-lit -a tools/bolt/test/X86/zero-density.s
```
2025-06-27 12:52:37 -07:00
Sterling-Augustine
23f1ba3ee4
Reapply "[NFC][DebugInfo][DWARF] Create new low-level dwarf library (#… (#145959) (#146112)
Reapply "[NFC][DebugInfo][DWARF] Create new low-level dwarf library (#…
(#145959)
    
This reapplies cbf781f0bdf2f680abbe784faedeefd6f84c246e, with fixes for
the shared-library build and the unconventional sanitizer-runtime build.

Original Description:

This is the culmination of a series of changes described in [1].
    
Although somewhat large by line count, it is almost entirely mechanical,
creating a new library in DebugInfo/DWARF/LowLevel. This new library has
very minimal dependencies, allowing it to be used from more places than
the normal DebugInfo/DWARF library--in particular from MC.
    
1.
https://discourse.llvm.org/t/rfc-debuginfo-dwarf-refactor-into-to-lower-and-higher-level-libraries/86665/2
2025-06-27 11:05:49 -07:00
Maksim Panchenko
d00c83ef22
[BOLT] Skip creation of new segments (#146023)
When all section contents are updated in-place, we can skip creation of
new segment(s), save disk space, and free up low memory addresses.

Currently, this feature only works with --use-gnu-stack.
2025-06-27 09:12:08 -07:00
Sterling-Augustine
5d03e7a204
Revert "[NFC][DebugInfo][DWARF] Create new low-level dwarf library (#… (#145959)
…145081)"

This reverts commit cbf781f0bdf2f680abbe784faedeefd6f84c246e.

Breaks a couple of buildbots.
2025-06-26 13:09:20 -07:00
Maksim Panchenko
4308292d1e
[BOLT] Refactor NewTextSegmentAddress handling (#145950)
Refactor the code for NewTextSegmentAddress to correctly point at the
true start of the segment when PHDR table is placed at the beginning. We
used to offset NewTextSegmentAddress by PHDR table plus cache line
alignment.

NFC for proper binaries. Some YAML binaries from our tests will diverge
due to bad segment address/offset alignment.
2025-06-26 12:09:11 -07:00
Sterling-Augustine
cbf781f0bd
[NFC][DebugInfo][DWARF] Create new low-level dwarf library (#145081)
This is the culmination of a series of changes described in [1].
    
Although somewhat large by line count, it is almost entirely mechanical,
creating a new library in DebugInfo/DWARF/LowLevel. This new library has
very minimal dependencies, allowing it to be used from more places than
the normal DebugInfo/DWARF library--in particular from MC.
    
I am happy to put it in another location, or to structure it differently
if that makes sense. Some have suggested in BinaryFormat, but it is not
a great fit there. But if that makes more sense to the reviewers, I can
do that.
 
Another possibility would be to use pass-through headers to allow
clients who don't care to depend only on DebugInfo/DWARF. This would be
a much less invasive change, and perhaps easier for clients. But also a
system that hides details.

Either way, I'm open.

1.
https://discourse.llvm.org/t/rfc-debuginfo-dwarf-refactor-into-to-lower-and-higher-level-libraries/86665/2
2025-06-26 11:23:46 -07:00
Anatoly Trosinenko
7a5af4f6b8
[BOLT] Gadget scanner: detect untrusted LR before tail call (#137224)
Implement the detection of tail calls performed with untrusted link
register, which violates the assumption made on entry to every function.

Unlike other pauth gadgets, detection of this one involves some amount
of guessing which branch instructions should be checked as tail calls.
2025-06-26 12:37:25 +03:00
Paschalis Mpeis
249f074b22
[BOLT][AArch64] Make gs-pacret-autiasp.s deterministic (#145527)
In gs-pacret-autiasp.s, the undefined call `bl g` causes inconsistent
basic block splitting: in some platforms BOLT emits two blocks, on some
others one.

Defining a dummy `g` symbol forces a single basic block everywhere.
2025-06-26 09:33:49 +01:00
Paschalis Mpeis
d681c73a04
[BOLT] Create marker for source changes in nfc-mode testing. (#142931)
Currently NFC tests only trigger when the llvm-bolt binary itself
changes.

This patch adds `--check-bolt-sources`, which scans git output for any
modifications under bolt/, excluding:
- bolt/docs
- bolt/utils/docker
- bolt/utils/dot2html

If any matching files change between versions, a `.llvm-bolt.changes`
marker is created. Buildbots can then use this marker to trigger in-tree
tests.
2025-06-26 09:32:20 +01:00
Amir Ayupov
49847148d4
[BOLT] Fix density for jump-through functions (#145619)
Address the issue that stems from how the density is computed.

Binary *function* density is the ratio of its total dynamic number of
executed bytes over the static size in bytes. The meaning of it is the
amount of dynamic profile information relative to its static size.

Binary *profile* density is the minimum *function* density among *well-
-profiled* functions, taken as functions covering p99 samples, or, in
other words, excluding functions in the tail 1% of samples. p99 is an
arbitrary cutoff. The meaning of profile density is the *minimum amount
of profile information per function* to be able to optimize the program
well. The threshold for profile density is set empirically.

The dynamically executed bytes are taken directly from LBR fall-throughs
and for LBRs recorded in trampoline functions, such as
```
000000001a941ec0 <Sleef_expf8_u10>:
1a941ec0: jmpq *0x37b911fa(%rip) # <pnt_expf8_u10>
1a941ec6: nopw %cs:(%rax,%rax)
```
the fall-through has zero length:
```
# Branch   Target   NextBranch  Count
T 1b171cf6 1a941ec0 1a941ec0    568562
```

But it's not correct to say this function has zero executed bytes, just
the size of the next branch is not included in the fall-through.

If such functions have non-trivial sample count, they will fall in p99
samples, and cause the profile density to be zero.

To solve this, we can either:
1. Include fall-through end jump size into executed bytes:
   is logically sound but technically challenging: the size needs to
   come from disassembly (expensive), and the threshold need to be
   reevaluated with updated definition of binary function density.
2. Exclude pass-through functions from density computation:
   follows the intent of profile density which is to set the amount of 
   profile information needed to optimize the function well. Single
   instruction pass-through functions don't need samples many times 
   the size to be optimized well.

Go with option 2 as a reasonable compromise.

Test Plan: added bolt/test/X86/zero-density.s
2025-06-25 22:20:37 -07:00
Benjamin Kramer
357297c0f2 [bolt] Fix the build after 0556a2aa187b86c28a9441aec3e98b9780a2c9ee
StringRef now implictly converts into ArrayRef<char>.
2025-06-25 20:16:19 +02:00
Anatoly Trosinenko
a8a2c6fa88
[BOLT] Gadget scanner: fix LR to be safe in leaf functions without CFG (#141824)
After a label in a function without CFG information, use a reasonably
pessimistic estimation of register state (assume that any register that
can be clobbered in this function was actually clobbered) instead of the
most pessimistic "all registers are unsafe". This is the same estimation
as used by the dataflow variant of the analysis when the preceding
instruction is not known for sure.

Without this, leaf functions without CFG information are likely to have
false positive reports about non-protected return instructions, as
1) LR is unlikely to be signed and authenticated in a leaf function and
2) LR is likely to be used by a return instruction near the end of the
   function and
3) the register state is likely to be reset at least once during the
   linear scan through the function
2025-06-25 13:11:23 +03:00