You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
expand: Add new clrsb fallback expansion [PR101950]
As suggested in the PR, the following patch adds two new clrsb
expansion possibilities if target doesn't have clrsb_optab for the
requested nor wider modes, but does have clz_optab for the requested
mode.
One expansion is
clrsb (op0)
expands as
clz (op0 ^ (((stype)op0) >> (prec-1))) - 1
which is usable if CLZ_DEFINED_VALUE_AT_ZERO is 2 with value
of prec, because the clz argument can be 0 and clrsb should give
prec-1 in that case.
The other expansion is
clz (((op0 << 1) ^ (((stype)op0) >> (prec-1))) | 1)
where the clz argument is never 0, but it is one operation longer.
E.g. on x86_64-linux with -O2 -mno-lzcnt, this results for
int foo (int x) { return __builtin_clrsb (x); }
in
- subq $8, %rsp
- movslq %edi, %rdi
- call __clrsbdi2
- addq $8, %rsp
- subl $32, %eax
+ leal (%rdi,%rdi), %eax
+ sarl $31, %edi
+ xorl %edi, %eax
+ orl $1, %eax
+ bsrl %eax, %eax
+ xorl $31, %eax
and with -O2 -mlzcnt:
+ movl %edi, %eax
+ sarl $31, %eax
+ xorl %edi, %eax
+ lzcntl %eax, %eax
+ subl $1, %eax
On armv7hl-linux-gnueabi with -O2:
- push {r4, lr}
- bl __clrsbsi2
- pop {r4, pc}
+ @ link register save eliminated.
+ eor r0, r0, r0, asr #31
+ clz r0, r0
+ sub r0, r0, #1
+ bx lr
As it (at least usually) will make code larger, it is
disabled for -Os or cold instructions.
2021-08-19 Jakub Jelinek <[email protected]>
PR middle-end/101950
* optabs.c (expand_clrsb_using_clz): New function.
(expand_unop): Use it as another clrsb expansion fallback.
* gcc.target/i386/pr101950-1.c: New test.
* gcc.target/i386/pr101950-2.c: New test.
0 commit comments