Is it possible to disable a specific instruction in AArch64?

Instructions like tbz have a limited range and possibly lead to overflow during relocation. I met this problem when I play with basic-block-section options.

My workaround is to add the pass to convert all tbz to and+cbz. Is there any way to disable it from clang?

No, there’s not a subtarget feature you can turn off to prevent generating tbz, and this is unlikely to be something we would accept, as tbz is part of the base architecture.

Linkers solve a similar problem using “range extension thunks”, which you may need to teach BOLT how to generate (and place?) these for your instructions. These are not allowed for tbz on AArch64 ELF, but apparently they are in COFF ⚙ D57575 [LLD] [COFF] Create range extension thunks for ARM64 (and the rules that BOLT follows may mean it can insert something like these in ELF). The other option is to implement, in BOLT, something a bit like LLVM’s Branch Relaxation Pass, though I’m not sure that helps very much. Looking at the AArch64 hooks for Branch Relaxation, though, I see that you might be able to use the internal LLVM option -aarch64-tbz-offset-bits=0 which may get branch relaxation to remove tbz. As this is an internal option, you should not rely on this long term.

I don’t know much about BOLT, but I think that llvm-project/LongJmp.cpp at main · llvm/llvm-project · GitHub is a pass which does insert longer jumps, on AArch64? Maybe this is something you can look into extending to support tbz relocations?