我在Compiler Explorer中摆弄东西,发现传递给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 System V在xmm0,xmm1等中传递FP args,并在xmm0中返回。)
我的问题是:为什么编译器不切换参数本身的顺序,所以这movapd
是没有必要的?当然必须知道,minsd的参数顺序不会改变答案吗?有没有我不喜欢的副作用?