Add a note about efficient codegen for binary log.
llvm-svn: 135996
This commit is contained in:
parent
442d1b199f
commit
c956033947
|
@ -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).
|
||||
|
||||
//===---------------------------------------------------------------------===//
|
||||
|
|
Loading…
Reference in New Issue