Skip to content

Instantly share code, notes, and snippets.

@d3x0r
Last active May 18, 2020 00:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save d3x0r/5d1d24536886e795531578c74059349e to your computer and use it in GitHub Desktop.
Save d3x0r/5d1d24536886e795531578c74059349e to your computer and use it in GitHub Desktop.
Trust in the Optimizer ???
// test available here
// https://godbolt.org/z/EiXxwW
// This is the basic function
int upTree( int N ) {
int n;
for( n = 0; n < 32; n++ ) if( !(N&(1<<n)) ) break;
return (N & ~((0x1)<<(n+1))) | ( 0x01 << n );
}
// THese are alternative endings...
#if _ALTERNATE_ENDINGS_
int val = (0x2)<<(n);
return (N & ~(val<<1)) | (val);
return (N & ~val) | ( val>>1 );
return (N & ~((0x2)<<(n))) | ( 0x01 << n );
return (N & ~((0x1)<<(n+1))) | ( 0x01 << n );
#endif
// These are optimized code generated on godbolt.org, with GCC 10.1 -O3...
#if 0
return (N & ~((0x2)<<(n))) | ( 0x01 << n );
not eax
and edi, eax
mov eax, edi
bts eax, ecx
ret
return (N & ~((0x1)<<(n+1))) | ( 0x01 << n );
btr edi, ecx
mov eax, edi
bts eax, edx
ret
mov eax, 2
sal eax, cl
mov edx, eax
return (N & ~(val<<1)) | (val);
add eax, eax
not eax
and edi, eax
mov eax, edi
or eax, edx
ret
mov edx, 2
sal edx, cl
return (N & ~val) | ( val>>1 );
mov eax, edx
not eax
and edi, eax
mov eax, edx
sar eax
or eax, edi
ret
#endif
// These are What was generated by MinGW 7.2.0 -O3
//return (N & ~((0x1)<<(n+1))) | ( 0x01 << n );
#if 0
0x000000000040158f <+31>: mov r8d,0x1
0x0000000000401595 <+37>: mov r9d,r8d
0x0000000000401598 <+40>: shl r9d,cl
0x000000000040159b <+43>: mov ecx,r9d
0x000000000040159e <+46>: not ecx
0x00000000004015a0 <+48>: and eax,ecx
0x00000000004015a2 <+50>: mov ecx,edx
0x00000000004015a4 <+52>: shl r8d,cl
0x00000000004015a7 <+55>: or eax,r8d
0x00000000004015aa <+58>: ret
#endif
int const val = (0x1)<<(n);
return (N & ~val) | ( val>>1 );
#if 0
0x000000000040158d <+29>: mov $0x1,%edx
0x0000000000401592 <+34>: shl %cl,%edx
0x0000000000401594 <+36>: mov %edx,%ecx
0x0000000000401596 <+38>: sar %edx
0x0000000000401598 <+40>: not %ecx
0x000000000040159a <+42>: and %ecx,%eax
0x000000000040159c <+44>: or %edx,%eax
0x000000000040159e <+46>: retq
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment