Instruction
BSR
Writes the index of the highest set bit of the source to the destination; a zero source sets ZF and leaves the destination unchanged.
- Extensions
- Forms
- 2 (2 Legacy)
- Data
- Intel XED v2026.08.23
BSR finds the highest set bit of its source and writes that bit’s index to the destination: for 0x28 it gives 5. For a nonzero x that index is the integer part of log2(x), one less than the number of bits x needs. Like BSF, it clears ZF when it finds a bit, and for a zero source sets ZF and leaves the destination unwritten; the other flags are undefined.
From C
C has no log2 for integers, but the index is 31 minus the count of leading zeros, and GCC 14 and Clang 23 at -O2 use BSR for both:
31 - __builtin_clz(x)becomes a lonebsr eax, edi;__builtin_clz(x)becomesbsr eax, ediandxor eax, 31, the XOR being a cheap 31 minus for a value between 0 and 31;32 - __builtin_clz(x), the bit width, becomes BSR and an addition of 1.
C leaves __builtin_clz(0) undefined, which matches BSR leaving the
destination alone. For x ? __builtin_clz(x) : 32, Clang relies on
that: it loads 63 into EAX, runs bsr eax, edi and XORs with 31,
which turns the untouched 63 into 32. GCC tests x and branches
instead. As on the BSF page, Intel’s manual warns that some older
processors clear bits 63:32 of the destination when a 32-bit BSR finds
nothing; Zen 5 kept them.
BSR is not LZCNT
LZCNT is encoded as BSR with an F3 prefix, but unlike
TZCNT and BSF it counts from the other side: it
returns 31 minus BSR’s answer for a 32-bit operand. A processor
without LZCNT ignores the prefix and returns the index instead of the
count, so compilers do not emit rep bsr; they use BSR and the XOR
unless allowed LZCNT. With -mlzcnt, Clang still compiles
31 - __builtin_clz(x) to a plain BSR, while GCC computes it as 31
minus an LZCNT.
Speed
Intel’s optimization manual lists BSR among the instructions of the one “Slow Int” execution unit of Golden Cove, with MUL and SHLD (Table 2-4). The instruction table of AMD’s Zen 5 guide lists BSR as one macro-op with a latency of one cycle.
In the optimization guide
What the optimization guide says about BSR, a line per claim. Each links to the claim in the guide, with its sources and where they differ.
Golden Cove and Raptor Cove
- Integer execution: Port 1 alone runs the slower integer operations: multiplication, PDEP and PEXT,
popcnt,bsr,crc32and the double shifts with an immediate count, which LLVM’s models give a latency of three cycles and one per cycle.
Jaguar and Puma
- Integer execution: LZCNT and POPCNT take one cycle on either ALU and TZCNT two, while BSF and BSR are microcoded, of seven and eight macro-ops and 4 and 5 cycles, so the newer instructions are the better choice where the zero case allows.
Skylake to Cooper Lake
- Integer execution: Port 1 alone runs integer multiplication, PDEP and PEXT,
popcnt,lzcnt,tzcnt,bsf,bsrand the double shifts, with a latency of three cycles and one a cycle in LLVM’s models, as on Golden Cove.
Zen and Zen+
- Integer execution: BSF and BSR are six macro-ops with a latency of three and four cycles, while LZCNT and POPCNT are one macro-op of one cycle and TZCNT two of two cycles. sources differ
Zen 2
- Integer execution: BSF and BSR are six macro-ops with a latency of three and four cycles, while LZCNT and POPCNT are one macro-op of one cycle and TZCNT two; LLVM’s model agrees.
Forms
| Instruction | Encoding | Requires |
|---|---|---|
BSR r16/32/64, m16/32/64
BSR_GPRv_MEMv | 0F BD /rF3 0F BD /r (without LZCNT) | Base instruction set |
BSR r16/32/64, r16/32/64
BSR_GPRv_GPRv | 0F BD /rF3 0F BD /r (without LZCNT) | Base instruction set |
Latency and throughput
| Model | r16, m16r32, m32r64, m64 | r16, r16r32, r32r64, r64 |
|---|---|---|
| Sandy Bridge, Haswell, Broadwell, Skylake, Skylake-SP, Ice Lake, Alder Lake, Sapphire Rapids | 8 / 1p1 | 3 / 1p1 |
| Lunar Lake | 7 / 0.33p135 | 3 / 0.33p135 |
| Bonnell | 16 / 16p1 | 16 / 16p01 |
| Silvermont | 13 / 10IEC0 IEC1 MEC | 10 / 10IEC0 IEC1 |
| Piledriver | 8 / 4EX0 EX1 | 4 / 4EX0 EX1 |
| Zen, Zen 2 | 8 / 4ALU0 ALU1 ALU2 ALU3 | 4 / 4ALU0 ALU1 ALU2 ALU3 |
| Zen 3 | 8 / 4ALU1 | 4 / 4ALU1 |
| Zen 4 | 5 / 1ALU1 | 1 / 1ALU1 |
| Jaguar | 8 / 4ALU0 ALU1 | 5 / 4ALU0 ALU1 |
Operation
What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.
s = src.read()
if s == 0:
zf = 1
# dest is not written, as both manuals say; Intel's adds
# that some older processors clear bits 63:32 of it at a
# 32-bit operand size
else:
zf = 0
for i in range(OSIZE):
if s >> i & 1:
n = i # the last 1 bit found is the highest
dest.write(n) # a 32-bit register: bits 63:32 cleared
of = sf = af = pf = cf = UNDEFINEDRun on AMD Zen 5 (EPYC 9645): 78 cases.
Operands
| Operand | Kind | Action |
|---|---|---|
BSR r16/32/64, r/m16/32/64 | ||
r16/32/64 | explicit | conditional write |
r/m16/32/64 | explicit | read |
RFLAGS | implicit | write |
Flags
| OF | SF | ZF | AF | PF | CF |
|---|---|---|---|---|---|
| All forms | |||||
| U | U | M | U | U | U |
Intrinsics
The C intrinsics of Clang 23.1.2 that compile to BSR, each with the form it compiles to and the Clang options it needs. The forms come from compiling every intrinsic and decoding the result with Intel XED; all intrinsics A–Z explains the method.
| Intrinsic | Compiles to |
|---|---|
_bit_scan_reverse
int _bit_scan_reverse(int A) |
|
__bsrd
int __bsrd(int __A) |
|
__bsrq
int __bsrq(long long __A) |
|
CPUID and processors
Each form belongs to an XED ISA set. A form can be used when the processor reports every CPUID bit of one of its ISA set's alternatives.
| ISA set | CPUID | Processors |
|---|---|---|
I386 | No CPUID bit: part of the base instruction set. | Every x86-64 processor in XED’s model and Zen 3 to Zen 6 |
More General-purpose instructions
Sources
- Intel XED v2026.08.23 (commit
0bcb6237345c): forms, encodings, operands, flags, exception classes, attributes, ISA sets, CPUID bits and chip model. - The CPU data of x86-64.net: Zen 3 to Zen 6, from GCC’s
-marchfeature sets and AMD’s Processor Programming References, which the page of each processor cites. - Clang's x86 intrinsic headers, LLVM 23.1.2 (commit
85ac56026243): the intrinsics, their signatures and doc comments, and the Clang of that release, which compiled each of them. - LLVM 23.1.2's x86 scheduling models (commit
85ac56026243): the latency, reciprocal throughput and ports of each form, as llvm-mca reports them. - Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 2 (325383-093, September 2026): Volume 2A, page 3-109 (BSR)
- AMD64 Architecture Programmer's Manual, Volume 3: General-Purpose and System Instructions (24594, rev. 3.39, October 2026)
- Intel 64 and IA-32 Architectures Optimization Reference Manual, Volume 1 (248966-051, October 2026)
- Software Optimization Guide for the AMD Zen5 Microarchitecture (58455, rev. 1.00, August 2024), Wayback Machine copy of AMD's ZIP
The tables are derived from Intel XED, Copyright Intel Corporation, licensed under the Apache License 2.0; x86-64.net converted and reformatted them. The intrinsics and their signatures come from Clang and the timings from LLVM's scheduling models, both part of the LLVM Project, licensed under the Apache License 2.0 with LLVM Exceptions. The text is our own.