https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107671
--- Comment #5 from Iain Buclaw <ibuclaw at gdcproject dot org> --- (In reply to Uroš Bizjak from comment #4) > from: > movl %esi, %ecx > movl $1, %eax > sall %cl, %eax > testl %edi, %eax > setne %al > movzbl %al, %eax > > to: > xorl %eax, %eax > btl %esi, %edi > setc %al > > The patch adapts *jcc_bt patterns to similar *scc_bt patterns. Thanks, have been tinkering with the pointer index version, and found that I can coax scc_bt_mask to match if I cast the lhs to a signed type. It's not obvious to me why there would be a difference. return ((__INT32_TYPE__)p[bitnum >> 5] & (1 << (bitnum & 31))) != 0; movl %esi, %eax shrl $5, %eax movl (%rdi,%rax,4), %eax btl %esi, %eax setc %al Things get even stranger once I expand to "bit test and op" variants though (better to put in another PR though) __INT32_TYPE__ btc32(__UINT32_TYPE__ *p, __UINT32_TYPE__ bitnum) { __INT32_TYPE__ result = ((__INT32_TYPE__)p[bitnum >> 5] & (1 << (bitnum & 31))) != 0; p[bitnum >> 5] ^= 1 << (bitnum & 31); return result; } Patch changes code-gen in the following way. from: movl %esi, %eax movl %esi, %ecx shrl $5, %eax leaq (%rdi,%rax,4), %rdx movl (%rdx), %eax movl %eax, %esi sarl %cl, %eax btcl %ecx, %esi andl $1, %eax movl %esi, (%rdx) to: movl %esi, %eax shrl $5, %eax leaq (%rdi,%rax,4), %rdx movl (%rdx), %eax movl %eax, %ecx btcl %esi, %ecx btl %esi, %eax setc %al movl %ecx, (%rdx) movzbl %al, %eax