[lld] [lld][ARM] Don't emit veneers for wraparound branches. (PR #165263)
Peter Smith via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 27 19:33:23 PDT 2025
https://github.com/smithp35 commented:
I didn't try and support the branch around the address space as I wasn't sure that this was entirely legal according to the Arm ARM. It does happen to work on a lot of Arm CPUs but I wasn't sure if that was something we could rely on architecturally.
I've put what I've found in the various Arm ARMs. From what I've been able to find it seems fine, apart from v8-A and above, where I think it is UNKNOWN (and hence can't be relied on). This could just be my reading of the Arm ARM though as the UNKNOWN parts may not be related to branch instructions.
Would you be able to check the Arm ARM to see whether you can find out if this is architecturally legal on v8-A? If it isn't then we could use the build attributes to see if at least one object is v8-a or above and suppress the wrap-around there.
v8-m Arm ARM suggests that this is supported
```
B7.4 Address space
The address space is a single, flat address space of 232 bytes.
Applies to an implementation of the architecture Armv8.0-M onward.
In the address space, byte addresses are unsigned numbers in the range 0-(232-1).
Applies to an implementation of the architecture Armv8.0-M onward.
If an address calculation overflows or underflows the address space, it wraps around. Address calculations are modulo 232.
```
As does the v7-ar Arm ARM
```
Address space overflow or underflow
Address space overflow occurs when the memory address increments beyond the top byte of the address space at 0xFFFFFFFF. When this happens, the address wraps round, so that, for example, incrementing 0xFFFFFFFF by 2 gives a result of 0x00000001.
Address space underflow occurs when the memory address decrements below the first byte of the address space at 0x00000000. When this happens, the address wraps round, so that, for example, decrementing 0x00000002 by 4 gives a result of 0xFFFFFFFE.
```
Arm v8-A for the 32-bit section is not as helpful. The pseudo code for branch instruction just has PC + imm32 which is passed as a 32-bit type.
```
E2.1.1 Address space
...
Address calculations are performed modulo 232.
The result of an address calculation is UNKNOWN if it overflows or underflows the 32-bit address range A[31:0].
```
Where UNKNOWN has this clause
```
An UNKNOWN value must not be documented or promoted as having a defined value or effect.
```
There is a section on address space underflow/overflow which unlike v7-A is explicitly UNKNOWN, however it only seems to apply to an instruction that after execution causes the PC to wrap round
```
Address space overflow or underflow
When a PE performs a normal, sequential execution of instructions, it calculates:
(address_of_current_instruction) + (size_of_executed_instruction)
This calculation is performed after each instruction to determine which instruction to execute next. If the address calculation performed after executing an A32 or T32 instruction overflows 0xFFFF FFFF, the Program Counter becomes UNKNOWN.
```
https://github.com/llvm/llvm-project/pull/165263
More information about the llvm-commits
mailing list