__builtin_c[tl]z accepts unsigned int argument that is not always the
same as uint32_t. For example, unsigned int is uint16_t on MSP430.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
We've run with changes like this for a long time to make the routines work for our out of tree target where int is also 16 bits so thumbs up from me even if I'm not sure I can formally LGTM it.
d.s.low and d.s.high are su_int. While some helpers from libgcc are documented with int, long, etc. types for simplicity and use machine modes under the hood, the __builtin_ctz() function (as well as clz), on the other hand, seems to really accept an int-sized argument:
$ clang --version clang version 10.0.0-4ubuntu1 Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /usr/bin $ clang -S -O3 -o- -x c - <<< "int f() { return __builtin_ctz(0x100000); }" .text .file "-" .globl f # -- Begin function f .p2align 4, 0x90 .type f,@function f: # @f .cfi_startproc # %bb.0: movl $20, %eax retq .Lfunc_end0: .size f, .Lfunc_end0-f .cfi_endproc # -- End function .ident "clang version 10.0.0-4ubuntu1 " .section ".note.GNU-stack","",@progbits .addrsig $ clang -S -O3 -target msp430 -o- -x c - <<< "int f() { return __builtin_ctz(0x100000); }" <stdin>:1:32: warning: implicit conversion from 'long' to 'unsigned int' changes value from 1048576 to 0 [-Wconstant-conversion] int f() { return __builtin_ctz(0x100000); } ~~~~~~~~~~~~~ ^~~~~~~~ .text .file "-" .globl f ; -- Begin function f .p2align 1 .type f,@function f: ; @f ; %bb.0: ret .Lfunc_end0: .size f, .Lfunc_end0-f ; -- End function .ident "clang version 10.0.0-4ubuntu1 " .section ".note.GNU-stack","",@progbits .addrsig 1 warning generated.
I checked this, and it seems good to me although I would like someone else to also take a look.
I can confirm this. This is why I introduced the clzsi and ctzsi macros in D78662. They are not intended for use with plain int types, but for use with si_int / su_int types (that are always 32-bit, unlike int).
Looks good to me.
compiler-rt/lib/builtins/fp_extend.h | ||
---|---|---|
32–39 | Perhaps more reliable would be the following: #if ULONG_MAX == 0xFFFFFFFFFFFFFFFF return __builtin_clzl(a); #elif ULLONG_MAX == 0xFFFFFFFFFFFFFFFF return __builtin_clzll(a); #else #error Unsupported platform #endif This is what I've also used in int_types.h to detect clzsi etc. It probably would need to be tested on some more architectures though (32 and 64 bit). |
compiler-rt/lib/builtins/fp_extend.h | ||
---|---|---|
32–39 | In fact, it might be possible to use __builtin_clzll for all platforms (it maps to 'long long', which I think is 64-bit practically everywhere). |
Perhaps more reliable would be the following:
This is what I've also used in int_types.h to detect clzsi etc. It probably would need to be tested on some more architectures though (32 and 64 bit).