This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Mined out of comp.std.c...


... an interesting microoptimization.

The original post on comp.std.c is about whether

static int int_max (int a, int b) {
    int d = (b - a);
    return (b - d) & (d >> (CHAR_BIT*sizeof(int) - 1));
}

is or is not portable within the standard.  If you have twos-
complement arithmetic and >> does arithmetic right shift, it's
equivalent to the usual ((a > b) ? a : b).

More interesting to me is the observation that - since we know the
arithmetic properties of the target - we could transform 
((a > b) ? a : b) into the above, if it were a win.  What I'm
wondering is if it is.  On an i386, it's definitely not a space win:

   8:   89 c2                   mov    %eax,%edx
   a:   29 ca                   sub    %ecx,%edx
   c:   29 d0                   sub    %edx,%eax
   e:   c1 fa 1f                sar    $0x1f,%edx
  11:   21 d0                   and    %edx,%eax

vs.

  28:   39 d0                   cmp    %ecx,%eax
  2a:   7d 02                   jge    2e <int_max_2+0xe>
  2c:   89 d0                   mov    %ecx,%eax

or

  28:   39 c2                   cmp    %eax,%ecx
  2a:   0f 4d c2                cmovge %ecx,%eax

(input parameters in eax, ecx in all three cases).  It's unlikely that
the clever bit shifts are faster than the conditional move, especially
in real life where we would be able to schedule other ops between the
cmp and the cmovge.  However, shifts might well be faster than jumps.
Anyone know for sure?

zw


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]