Pourquoi les compilateurs insistent-ils ici pour utiliser un registre enregistré par l'appelé?

Considérez ce code C: void foo(void); long bar(long x) { foo(); return x; } Quand je le compile sur GCC 9.3 avec -O3ou -Os, j'obtiens ceci: bar: push r12 mov r12, rdi call foo mov rax, r12 pop r12 ret La sortie de clang est identique, sauf pour choisir rbxau lieu de r12comme registre enregistré par...