use*_*424 4 c optimization clang compiler-optimization
在使用OSX High Sierra上的clang编译-O3代码时遇到了一个有趣的问题.代码是这样的:
#include <stdint.h>
#include <limits.h> /* for CHAR_BIT */
#include <stdio.h> /* for printf() */
#include <stddef.h> /* for size_t */
uint64_t get_morton_code(uint16_t x, uint16_t y, uint16_t z)
{
/* Returns the number formed by interleaving the bits in x, y, and z, also
* known as the morton code.
*
* See https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableO
bvious.
*/
size_t i;
uint64_t a = 0;
for (i = 0; i < sizeof(x)*CHAR_BIT; i++) {
a |= (x & 1U << i) << (2*i) | (y & 1U << i) << (2*i + 1) | (z & 1U << i)
<< (2*i + 2);
}
return a;
}
int main(int argc, char **argv)
{
printf("get_morton_code(99,159,46) = %llu\n", get_morton_code(99,159,46));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在编译时,cc -O1 -o test_morton_code test_morton_code.c我得到以下输出:
get_morton_code(99,159,46) = 4631995
Run Code Online (Sandbox Code Playgroud)
哪个是对的.但是,编译时cc -O3 -o test_morton_code test_morton_code.c:
get_morton_code(99,159,46) = 4294967295
Run Code Online (Sandbox Code Playgroud)
这是错的.
什么也奇怪的是,这个bug在切换时会出现在我的代码-O2到-O3,而在它上面的最小工作示例从去时,会出现-O1到-O2.
这是编译器优化中的一个错误,还是我做了一些愚蠢的事情,只有当编译器更积极地进行优化时才出现?
我正在使用以下版本的clang:
snotdaqs-iMac:snoFitter snoperator$ cc --version
Apple LLVM version 9.1.0 (clang-902.0.39.1)
Target: x86_64-apple-darwin17.5.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
Run Code Online (Sandbox Code Playgroud)
a3f*_*a3f 14
UndefinedBehaviorSanitizer非常有助于捕捉这些错误:
$ clang -fsanitize=undefined -O3 o3.c
$ ./a.out
o3.c:19:2: runtime error: shift exponent 32 is too large for 32-bit type 'unsigned int'
get_morton_code(99,159,46) = 4294967295
Run Code Online (Sandbox Code Playgroud)
一个可能的修复方法是用1Us 代替s 1ULL,a unsigned long long至少为64位,可以移动那么远.
当i循环中的15 2*i+2为32时,您正在移位a中unsigned int的位数unsigned int,这是未定义的.
您显然打算在64位字段中工作,因此将移位的左侧投射到uint64_t.
适当的printf格式uint64_t是get_morton_code(99,159,46) = %" PRIu64 "\n".PRIu64在<inttypes.h>标题中定义.
| 归档时间: |
|
| 查看次数: |
375 次 |
| 最近记录: |