我在编译器资源管理器中胡乱操作,发现传递给 std: : min 的参数顺序改变了发出的程序集。
double std_min_xy(double x, double y) {
return std::min(x, y);
}
double std_min_yx(double x, double y) {
return std::min(y, x);
}
这将被编译(例如,在 clang 9.0.0上使用 -O3)为:
std_min_xy(double, double): # @std_min_xy(double, double)
minsd xmm1, xmm0
movapd xmm0, xmm1
ret
std_min_yx(double, double): # @std_min_yx(double, double)
minsd xmm0, xmm1
ret
如果我将 std: : min 更改为一个老式的三元操作符,这种情况将持续存在。它还可以在我试用过的所有现代编译器(clang、 gcc、 icc)中持久存在。
底层指令是 minsd
。阅读文档时,minsd
的第一个参数也是答案的目的地。显然,xmm0是函数的返回值所在的位置,因此如果使用 xmm0作为第一个参数,则不需要 movapd
。但是如果 xmm0是第二个参数,那么它必须使用 movapd xmm0, xmm1
才能将值输入 xmm0。(编辑注意: 是的,X86-64系统 V在 xmm0、 xmm1等中传递 FP 参数,并在 xmm0中返回。)
我的问题是: 为什么编译器不改变参数本身的顺序,这样就不需要 movapd
了?它肯定知道,头脑中的论点顺序不会改变答案?是不是有什么副作用,我没注意到?