http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47521
Jeffrey A. Law <law at redhat dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2011.02.02 19:26:49 CC| |law at redhat dot com Summary|[4.4/4.5/4.6 Regression] |Unnecessary usage of edx |Unnecessary usage of edx |register |register | Ever Confirmed|0 |1 --- Comment #3 from Jeffrey A. Law <law at redhat dot com> 2011-02-02 19:26:49 UTC --- Removing the regression tag. The gcc-4.5 and trunk code, are in effect equivalent. The seemingly unnecessary use of %edx doesn't affect anything and is merely an artifact of it appearing earlier in the register file -- it has the same costs as other call-clobbered regs and the allocator will use the first one appearing in the register file when multiple regs have the same cost. Note that it is true that the code could be improved. This just isn't a regression. There's two paths to get the desired code. The first would involve some surgery to the register allocator. The key here is the pseudo holding "a". The cost analysis has %eax and %edi as having the same cost. Allocating into %eax allows the copy to the return value to be eliminated while allocating into %edi allows the copy from the incoming argument to be deleted. What the allocator fails to realize is that the cmov can be used to eliminate the copy to the return value. Thus it's actually better to hold "a" in %edi. Fixing the allocator to realize this (and in fact use the cmov to eliminate the trailing mov) would probably be a PITA. The other approach is to let combine combine the cmov & move to the return register, even though the latter is a move to a likely-spilled hardreg. We generally avoid such combinations as to avoid lengthening the lifetime of a likely spilled hardreg, but in this kind of situation, no lengthening would occur. A quick hack as proof of concept results in: testb $16, %dil # 36 *testqi_1_maybe_si/2 [length = 4] movl $1, %eax # 34 *movsi_internal/1 [length = 5] cmovne %edi, %eax # 19 *movsicc_noc/1 [length = 3] ret # 39 return_internal [length = 1]