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

Reply via email to