如何解决GCC优化遗漏错误90271?

ein*_*ica 5 c gcc compiler-optimization

在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;
}
Run Code Online (Sandbox Code Playgroud)

可以看出这里(GodBolt):铛优化此代码正确GCC和MSVC没有。这是GCC错误90271,它将在某个时候被修复。但是-它不会针对今天发布的GCC版本修复,我想今天编写这段代码...

那么:是否有一种解决方法可以使GCC为此功能生成与clang相同的代码,或者至少-具有相当性能的代码,将数据保存在寄存器中,而不求助于指针和堆栈?

笔记:

  • 我将其标记为C,因为代码段位于C中。我假设一种解决方法(如果存在)也可以在C中实现。
  • 我对同时优化非内联函数和内联版本很感兴趣。
  • 这个问题与有关,但在这里仅涉及GCC和代码段中的特定方法。并且使用C而不是C ++。

120*_*arm 7

这使非内联版本更长一些,但是内联版本针对所有三个编译器进行了优化:

int replace_bytes(int v1 ,char v2, size_t k)
{
    return (v1 & ~(0xFF << k * 8)) | ((unsigned char)v2 << k * 8);
}
Run Code Online (Sandbox Code Playgroud)

的演员v2unsigned char如果移位前,必须char是一个有符号的类型。在这种情况下,如果不使用大小写,v2则将符号扩展为整数,这将导致结果中不需要的位设置为1。