J'ai bricolé dans l'Explorateur de compilateurs, et j'ai découvert que l'ordre des arguments passés à std::min modifie l'assemblage émis.
Voici l'exemple sur Godbolt Compiler Explorer,l:%275%27,n:%270%27,o:%27C%2B%2B+source+%235%27,t:%270%27)),k:50,l:%274%27,n:%270%27,o:%27%27,s:0,t:%270%27),(g:!((h:compiler,i:(compiler:clang900,filters:(b:%270%27,binary:%271%27,commentOnly:%270%27,demangle:%270%27,directives:%270%27,execute:%271%27,intel:%270%27,libraryCode:%271%27,trim:%271%27),fontScale:14,j:1,lang:c%2B%2B,libs:!(),options:%27-O3%27,selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:5),l:%275%27,n:%270%27,o:%27x86-64+clang+9.0.0+(Editor+%235,+Compiler+%231)+C%2B%2B%27,t:%270%27)),header:(),k:50,l:%274%27,n:%270%27,o:%27%27,s:0,t:%270%27)),l:%272%27,n:%270%27,o:%27%27,t:%270%27)),version:4)
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);
}
Ceci est compilé (avec -O3 sur clang 9.0.0, par exemple), en :
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
Cela persiste si je change le std::min en un opérateur ternaire de la vieille école. Il persiste également avec tous les compilateurs modernes que j'ai essayés (clang, gcc, icc).
L'instruction sous-jacente est minsd
. En lisant la documentation, le premier argument de minsd
est également la destination de la réponse. Apparemment, xmm0 est l'endroit où ma fonction est censée mettre sa valeur de retour, donc si xmm0 est utilisé comme premier argument, il n'y a pas de réponse. movapd
nécessaire. Mais si xmm0 est le deuxième argument, alors il faut movapd xmm0, xmm1
pour obtenir la valeur dans xmm0. (note de l'éditeur : oui, Système V x86-64 passe les args FP dans xmm0, xmm1, etc., et retourne dans xmm0.)
Ma question : pourquoi le compilateur ne change-t-il pas l'ordre des arguments lui-même, de sorte que cette movapd
n'est pas nécessaire ? Il doit sûrement savoir que l'ordre des arguments de minsd ne change pas la réponse ? Y a-t-il un effet secondaire que je n'apprécie pas ?