If I compile the following code with Clang 3.3 using -O3 -fno-vectorize
I get the same assembly output even if I remove the commented line. The code type puns all possible 32-bit integers to floats and counts the ones in a [0, 1] range. Is Clang's optimizer actually smart enough to realize that 0xFFFFFFFF when punned to float is not in the range [0, 1], so ignore the second call to fn
entirely? GCC produces different code when the second call is removed.
#include <limits>
#include <cstring>
#include <cstdint>
template <class TO, class FROM>
inline TO punning_cast(const FROM &input)
{
TO out;
std::memcpy(&out, &input, sizeof(TO));
return out;
}
int main()
{
uint32_t count = 0;
auto fn = [&count] (uint32_t x) {
float f = punning_cast<float>(x);
if (f >= 0.0f && f <= 1.0f)
count++;
};
for(uint32_t i = 0; i < std::numeric_limits<uint32_t>::max(); ++i)
{
fn(i);
}
fn(std::numeric_limits<uint32_t>::max()); //removing this changes nothing
return count;
}
See here: http://goo.gl/YZPw5i