Skip to content

Commit

Permalink
use intrinsics correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
VSadov committed Dec 19, 2023
1 parent a7ca3a5 commit 14ef9e1
Showing 1 changed file with 12 additions and 9 deletions.
21 changes: 12 additions & 9 deletions src/coreclr/inc/gcinfotypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,28 +47,31 @@ __forceinline size_t SAFE_SHIFT_RIGHT(size_t x, size_t count)

inline UINT32 CeilOfLog2(size_t x)
{
// we want lzcnt, but bsr is ok too
// it is ok to use bsr or clz unconditionally
_ASSERTE(x > 0);

x = (x << 1) - 1;

#ifdef TARGET_64BIT
#ifdef _MSC_VER
DWORD lzcountCeil;
_BitScanReverse64(&lzcountCeil, (unsigned long)x);
DWORD result;
_BitScanReverse64(&result, (unsigned long)x);
return (UINT32)result;
#else // _MSC_VER
UINT32 lzcountCeil = (UINT32)__builtin_clzl((unsigned long)x);
// LZCNT returns index starting from MSB, whereas BSR gives the index from LSB.
// 63 ^ BSR here is equivalent to 63 - BSR since the BSR result is always between 0 and 63.
// This saves an instruction, as subtraction from constant requires either MOV/SUB or NEG/ADD.
return (UINT32)63 ^ (UINT32)__builtin_clzl((unsigned long)x);
#endif // _MSC_VER
#else // TARGET_64BIT
#ifdef _MSC_VER
DWORD lzcountCeil;
_BitScanReverse(&lzcountCeil, (unsigned long)x);
DWORD result;
_BitScanReverse(&result, (unsigned int)x);
return (UINT32)result;
#else // _MSC_VER
UINT32 lzcountCeil = (UINT32)__builtin_clz((unsigned int)x);
return (UINT32)31 ^ (UINT32)__builtin_clz((unsigned int)x);
#endif // _MSC_VER
#endif

return BITS_PER_SIZE_T - lzcountCeil;
}

enum GcSlotFlags
Expand Down

0 comments on commit 14ef9e1

Please sign in to comment.