http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54686
--- Comment #12 from Marc Glisse <glisse at gcc dot gnu.org> 2012-09-23 22:10:56 UTC --- (In reply to comment #11) > You really scared me now. > unsigned long is also a nop. That's only because unsigned long has less bits than the mantissa of double on your platform. On x86_64, it is converted to double (and converting between unsigned long and double is ugly). > *drumroll* > > bool bleh (bool x) > { > return std::abs (x); > } > > gets a fine floating treatment -- it is converted to double and then tested > for > != 0.0. Interesting. To clarify, 2 things happen. 1) __builtin_fabs seems to have some magic to detect that it is called on an unsigned type (bool included) and do nothing in that case. std::abs<unsigned> is thus reduced to a cast to double. 2) casting from an integer to double and back to an integer, if the original integer type is small enough that double can represent it exactly, the casts are collapsed. Casts to bool are represented internally as !=0, so the optimization is missed. You can file an RFE for that one if you want.