[llvm] [BOLT][AArch64] Treat `br x30` as a return (PR #159458)

Kristof Beyls via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 18 00:54:42 PDT 2025


kbeyls wrote:

Hmmm....

There are differences between the semantics of `RET x30` and `BR x30`.
For example, when the [Armv9.3 Guarded Control Stack feature](https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/arm-a-profile-architecture-2022) is enabled, the `BR` is not considered a return and does not alter the guarded control stack, while the `RET` is considered a return and does update the guarded control stack state. The pseudo code for the `RET` instruction contains the following pseudo-code, while the pseudo code for `BR` does not:
```
if IsFeatureImplemented(FEAT_GCS) && GCSPCREnabled(PSTATE.EL) then
    target = LoadCheckGCSRecord(target, GCSInstType_PRET);
    SetCurrentGCSPointer(GetCurrentGCSPointer() + 8);
```

Also for BTI (which is already widely deployed), there is a difference.
The `BR` pseudo code related to BTI is:
```
// Value in BTypeNext will be used to set PSTATE.BTYPE
if InGuardedPage then
  if n == 16 || n == 17 then
    BTypeNext = '01';
  else
    BTypeNext = '11';
else
    BTypeNext = '01';
```
whereas the `RET` pseudo code relate to BTI is:
```
// Value in BTypeNext will be used to set PSTATE.BTYPE
BTypeNext = '00';
```

As GCS (guarded control stack) gets deployed more widely, I would assume that most code that uses `BR x30` when it really should use `RET` will need to be updated.
Do you see `BR x30` frequently enough in code in the wild that it makes a meaningful difference to recognize it as a return in BOLT?

https://github.com/llvm/llvm-project/pull/159458


More information about the llvm-commits mailing list