arm64: Emit tbnz/tbz for sign-bit branch tests in branchTest32/branchTestPtr
| Assignee | |
Descriptionβ’2 months ago
|
branchTest32 and branchTestPtr in MacroAssembler-arm64-inl.h already recognize the test reg, reg idiom (where lhs == rhs) and emit cbz/cbnz for the Zero/NonZero conditions. However, the Signed/NotSigned conditions fall through to the generic path, which emits two instructions:
tst w0, w0
b.mi label
This patch extends the existing pattern to also handle Signed and NotSigned, emitting a single tbnz/tbz on the sign bit instead:
tbnz w0, #31, label (32-bit Signed)
tbz w0, #31, label (32-bit NotSigned)
tbnz x0, #63, label (64-bit Signed)
tbz x0, #63, label (64-bit NotSigned)
This saves one instruction per call site, avoids clobbering NZCV flags, and matches what LLVM already emits for equivalent sign-bit tests in AOT-compiled code (where sign-bit tbz/tbnz account for 1-4% of all instructions in typical arm64 binaries).
Call sites that benefit include visitModPowTwoI, visitModPowTwoI64, bailoutTest32(Signed, ...), and any other path through branchTest{32,Ptr}(Signed/NotSigned, r, r, ...).
Range safety: tbnz/tbz have a Β±32KB offset (14-bit immediate), tighter than b.cc's Β±1MB. Mozilla's vixl fork handles this via registerBranchDeadline with automatic veneer insertion, so arbitrarily distant labels degrade gracefully to a 2-instruction trampoline β no worse than the original code.
Verified with IONFLAGS=codegen that Ion emits tbnz/tbz for the targeted patterns. ./mach jit-test passes.
| Assignee | |
Comment 1β’2 months ago
|
Extend branchTest32/branchTestPtr to recognize the (Signed/NotSigned, r, r)
pattern and emit a single tbnz/tbz on bit 31/63 instead of tst + b.mi/b.pl.
Updatedβ’2 months ago
|
Updatedβ’1 month ago
|
Comment 2β’1 month ago
|
Comment 3β’1 month ago
|
|
| bugherder | |
Updatedβ’1 month ago
|
Updatedβ’26 days ago
|
