【发布时间】:2014-10-22 21:02:49
【问题描述】:
有符号整数溢出在 C 和 C++ 中未定义。但是__m128i 的各个字段中的有符号整数溢出呢?换句话说,这种行为是否在英特尔标准中定义?
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
#include <emmintrin.h>
union SSE2
{
__m128i m_vector;
uint32_t m_dwords[sizeof(__m128i) / sizeof(uint32_t)];
};
int main()
{
union SSE2 reg = {_mm_set_epi32(INT32_MAX, INT32_MAX, INT32_MAX, INT32_MAX)};
reg.m_vector = _mm_add_epi32(reg.m_vector, _mm_set_epi32(1, 1, 1, 1));
printf("%08" PRIX32 "\n", (uint32_t) reg.m_dwords[0]);
return 0;
}
[myria@polaris tests]$ gcc -m64 -msse2 -std=c11 -O3 sse2defined.c -o sse2defined
[myria@polaris tests]$ ./sse2defined
80000000
请注意,SSE2 __m128i 的 4 字节大小的字段被视为已签名。
【问题讨论】:
-
这是一个很好的问题!
-
在实践中,这些元素的行为符合预期,即正常的 2s 补码环绕等。我不知道您是否会在英特尔文档中找到任何东西来保证这一点。
-
SSE2
__mi128i(显然)是一个特定于体系结构的概念,因此 C 和 C++ 标准没有提及类型或其行为或内在。您需要查看“供应商”文档以了解超出标准所提供的任何保证。 -
Intel® 64 and IA-32 Architectures Software Developer’s Manual 表 9-2 将其列为 Wrap-around,但我找不到任何明确的保证
_mm_add_epi32永远不会被简单的 C 包装器模拟。 -
@thatotherguy:我不知道你认为
_mm_add_epi32()许可证的软件模拟会给出与PADDD不同的结果。
标签: c language-lawyer undefined-behavior sse2