我如何解决 GCC optimization-miss 错误 90271?
How can I work around GCC optimization-miss bug 90271?
2019 年 5 月之前(可能更晚)发布的 GCC 版本无法优化这段代码:
// Replace the k'th byte within an int
int replace_byte(int v1 ,char v2, size_t k)
{
memcpy( (void*) (((char*)&v1)+k) , &v2 , sizeof(v2) );
return v1;
}
可以看出 here (GodBolt): clang optimizes this code properly GCC and MSVC do not. This is GCC bug 90271,这将在某个时候得到修复。但是 - 它不会针对今天发布的 GCC 版本进行修复,我今天想写这段代码...
因此:是否有一种解决方法可以使 GCC 为该函数生成与 clang 相同的代码,或者至少 - 性能相当的代码,将数据保存在寄存器中而不求助于指针和堆栈?
备注:
- 我将其标记为 C,因为代码片段在 C 中。我假设有一种解决方法(如果存在)也可以在 C 中实现。
- 我有兴趣同时优化非内联函数和内联函数。
- 此问题与this one相关,但只涉及GCC和此处代码段的具体做法;并且使用 C 而不是 C++。
这使得非内联版本稍长一些,但内联版本针对所有三个编译器进行了优化:
int replace_bytes(int v1 ,char v2, size_t k)
{
return (v1 & ~(0xFF << k * 8)) | ((unsigned char)v2 << k * 8);
}
如果 char
是有符号类型,则必须在转换前将 v2
强制转换为 unsigned char
。在这种情况下,如果没有这种情况,v2
将被符号扩展为整数,这将导致在结果中将不需要的位设置为 1。
2019 年 5 月之前(可能更晚)发布的 GCC 版本无法优化这段代码:
// Replace the k'th byte within an int
int replace_byte(int v1 ,char v2, size_t k)
{
memcpy( (void*) (((char*)&v1)+k) , &v2 , sizeof(v2) );
return v1;
}
可以看出 here (GodBolt): clang optimizes this code properly GCC and MSVC do not. This is GCC bug 90271,这将在某个时候得到修复。但是 - 它不会针对今天发布的 GCC 版本进行修复,我今天想写这段代码...
因此:是否有一种解决方法可以使 GCC 为该函数生成与 clang 相同的代码,或者至少 - 性能相当的代码,将数据保存在寄存器中而不求助于指针和堆栈?
备注:
- 我将其标记为 C,因为代码片段在 C 中。我假设有一种解决方法(如果存在)也可以在 C 中实现。
- 我有兴趣同时优化非内联函数和内联函数。
- 此问题与this one相关,但只涉及GCC和此处代码段的具体做法;并且使用 C 而不是 C++。
这使得非内联版本稍长一些,但内联版本针对所有三个编译器进行了优化:
int replace_bytes(int v1 ,char v2, size_t k)
{
return (v1 & ~(0xFF << k * 8)) | ((unsigned char)v2 << k * 8);
}
如果 char
是有符号类型,则必须在转换前将 v2
强制转换为 unsigned char
。在这种情况下,如果没有这种情况,v2
将被符号扩展为整数,这将导致在结果中将不需要的位设置为 1。