Add a note about efficient codegen for binary log.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135996 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Benjamin Kramer 2011-07-25 22:30:00 +00:00
parent 9eff19896e
commit a3d782f40c

View File

@ -2066,3 +2066,51 @@ The trick is to match "fetch_and_add(X, -C) == C".
//===---------------------------------------------------------------------===//
unsigned log2(unsigned x) {
return x > 1 ? 32-__builtin_clz(x-1) : 0;
}
generates (x86_64):
xorl %eax, %eax
cmpl $2, %edi
jb LBB0_2
## BB#1:
decl %edi
movl $63, %eax
bsrl %edi, %ecx
cmovel %eax, %ecx
xorl $31, %ecx
movl $32, %eax
subl %ecx, %eax
LBB0_2:
ret
The cmov and the early test are redundant:
xorl %eax, %eax
cmpl $2, %edi
jb LBB0_2
## BB#1:
decl %edi
bsrl %edi, %ecx
xorl $31, %ecx
movl $32, %eax
subl %ecx, %eax
LBB0_2:
ret
If we want to get really fancy we could use some two's complement magic:
xorl %eax, %eax
cmpl $2, %edi
jb LBB0_2
## BB#1:
decl %edi
bsrl %edi, %ecx
xorl $-32, %ecx
leal 33(%ecx), %eax
LBB0_2:
ret
This is only useful on targets that can't encode the first operand of a sub
directly. The rule is C1 - (X^C2) -> (C1+1) + (X^~C2).
//===---------------------------------------------------------------------===//