【发布时间】:2021-05-25 18:25:09
【问题描述】:
我们正在使我们的项目兼容 GCC。 启用 LTO 后,链接需要很长时间,并且这些警告显示:
../src/xenia/base/memory.h: In function ‘copy_and_swap.constprop’:
../src/xenia/base/memory.cc:105: warning: iteration 4611686018427387903
invokes undefined behavior [-Waggressive-loop-optimizations]
105 | dest[i] = byte_swap(src[i]);
|
../src/xenia/base/memory.cc:104: note: within this loop
104 | for (; i < count; ++i) { // handle residual elements
|
../src/xenia/base/memory.cc:124: warning: iteration 4611686018427387903
invokes undefined behavior [-Waggressive-loop-optimizations]
124 | dest[i] = byte_swap(src[i]);
|
../src/xenia/base/memory.cc:123: note: within this loop
123 | for (; i < count; ++i) { // handle residual elements
|
这是我们第一次看到这些函数存在问题(通常使用 MSVC/Clang)。它们包括 向量内在函数。
如何调试此问题?如何获取调用 GCC 的编译时堆栈跟踪 正在尝试优化?
编辑:
这是有问题的代码
inline uint32_t byte_swap(uint32_t value) { return __builtin_bswap32(value); }
void copy_and_swap_32_aligned(void* dest_ptr, const void* src_ptr,
size_t count) {
assert_zero(reinterpret_cast<uintptr_t>(dest_ptr) & 0xF);
assert_zero(reinterpret_cast<uintptr_t>(src_ptr) & 0xF);
auto dest = reinterpret_cast<uint32_t*>(dest_ptr);
auto src = reinterpret_cast<const uint32_t*>(src_ptr);
__m128i shufmask =
_mm_set_epi8(0x0C, 0x0D, 0x0E, 0x0F, 0x08, 0x09, 0x0A, 0x0B, 0x04, 0x05,
0x06, 0x07, 0x00, 0x01, 0x02, 0x03);
size_t i;
for (i = 0; i + 4 <= count; i += 4) {
__m128i input = _mm_load_si128(reinterpret_cast<const __m128i*>(&src[i]));
__m128i output = _mm_shuffle_epi8(input, shufmask);
_mm_store_si128(reinterpret_cast<__m128i*>(&dest[i]), output);
}
for (; i < count; ++i) { // handle residual elements
dest[i] = byte_swap(src[i]);
}
}
没有内在函数的平台不变版本的函数(仅循环完整的数组和单独的字节交换)不会引发 gcc 警告。
【问题讨论】:
-
我不确切知道 gcc 将什么视为 UB,但我已经用一个可能更接近您的代码试图做的示例更新了我的帖子。
标签: gcc compiler-errors linker lto