[gcc flags: -O3 -funsigned-char] [ asm explorer ]
//partially optimized to: and, rol
unsigned int rol(unsigned int x, unsigned char r)
{
r &= 31; return (x << r) | (x >> (32-r));
}
//optimized to single: rol
unsigned int rol(unsigned int x, unsigned int r)
{
r &= 31; return (x << r) | (x >> (32-r));
}
如果使用 -da
编译并查看生成的*.combine
转储,您可以看到第二个函数成功匹配
(set (reg:SI 91)
(rotate:SI (reg/v:SI 89 [ x ])
(subreg:QI (and:SI (reg/v:SI 90 [ r ])
(const_int 31 [0x1f])) 0)))
而第一个失败
(set (reg:SI 93)
(rotate:SI (reg/v:SI 90 [ x ])
(and:QI (subreg:QI (reg:SI 92 [ r ]) 0)
(const_int 31 [0x1f]))))
从 int 到 char 和执行and
的顺序是不同的。Gcc 可能缺少将一个模式规范化的转换,或者在最坏的情况下缺少第二个模式。
如果您找不到类似的报告,请向 GCC 的 bugzilla 报告。