Skip to content

Conversation

RicoP
Copy link
Contributor

@RicoP RicoP commented Mar 2, 2025

sinfl_bsr has undefined behavior for compilers other than MSVC, GCC and clang (in my case Tiny C Compiler) because the function won't return anything at all.

I turned the #elif into a #else so on compilers other than MSVC sinfl_bsr will always rely on __builtin_clz. This can still cause a compile error on compilers that don't support __builtin_clz but at least we have a explicit error. Alternatively I could also implement sinfl_bsr by hand:

static int
sinfl_bsr(unsigned n) {
#ifdef _MSC_VER
  unsigned long r = 0;
  _BitScanReverse(&r, n);
  return int(r);
#elif defined(__GNUC__) || defined(__clang__) || defined(__TINYC__)
  return 31 - __builtin_clz(n);
#else  
    static const unsigned char table_2_32[32] = {
        31, 22, 30, 21, 18, 10, 29,  2, 20, 17, 15, 13,  9,  6, 28,  1,
        23, 19, 11,  3, 16, 14,  7, 24, 12,  4,  8, 25,  5, 26, 27,  0
    };
    n |= n >> 1;  
    n |= n >> 2;  
    n |= n >> 4;  
    n |= n >> 8;  
    n |= n >> 16; 
    n = table_2_32[(n * 0x07c4acddu) >> 27];
    return 31 - n;
#endif
}

I got this code from https://github.com/TinyCC/tinycc/blob/6ec4a106524ab6a6e3a4178774fd1e884d3fcce2/lib/builtin.c#L50

@vurtun vurtun merged commit 87c3565 into vurtun:master Mar 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants