我相信我在实现 O'Neill 的 PCG PRNG 时在 GCC 中发现了一个错误。(Godbolt 编译器资源管理器上的初始代码)
相乘后oldstate
通过MULTIPLIER
,(存储在RDI结果),GCC不该结果添加到INCREMENT
,movabs'ingINCREMENT
到RDX代替,然后把它用作rand32_ret.state的返回值
最小可重现示例(编译器资源管理器):
#include <stdint.h>
struct retstruct {
uint32_t a;
uint64_t b;
};
struct retstruct fn(uint64_t input)
{
struct retstruct ret;
ret.a = 0;
ret.b = input * 11111111111 + 111111111111;
return ret;
}
Run Code Online (Sandbox Code Playgroud)
生成的程序集(GCC 9.2、x86_64、-O3):
fn:
movabs rdx, 11111111111 # multiplier constant (doesn't fit in imm32)
xor eax, eax # ret.a = 0
imul rdi, rdx
movabs rdx, 111111111111 …
Run Code Online (Sandbox Code Playgroud)