int cmov(int* A ,int B ,int C ,int* D ,int* E ,int F ,int g) { int k,f; for (k = 1; k <= 1000; k++) { A[k] = B+C; g = D[k-1] + E[k-1]; if (g > A[k]) A[k]=g; /* This is not converted to cmov*/ f += g; } return f; }
In the above code, the if-then statement is not converted to conditional move. It fails for "noce_mem_write_may_trap_or_fault_p ()" condition in "ifcvt.c" as it thinks that there is a chance for A[k] access to trap. The fact here is that in this case, A[k] will never trap because the A[k] is already been written once along the path from Entry to the "A[k] = g". So it is safe to convert it to a cmov statement. Though there might be two extra moves (mem to reg and vice versa) statement, it is still better to avoid the branch especially if it is unpredictable data like for the eg above. There is a typical case like this in Spec 2006 456.hmmer benchmark. Using contional moves will make the code faster by 13%-17%. -Dwarak -- Summary: Does not emit conditional moves for stores Product: gcc Version: 4.2.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: dwarak dot rajagopal at amd dot com GCC build triplet: x86_64 GCC host triplet: x86_64 GCC target triplet: x86_64 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27313