http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50782

--- Comment #3 from Ethan Tira-Thompson <ejtttje at gmail dot com> 2011-10-18 
23:55:47 UTC ---
I figured out what I did differently, I did some 'minor cleanup' and moved n
out of the function scope.  This actually changes the optimization results.

This is just for reference in case you are interested:

Looking at the assembly for the three tests below, I confirmed printf is being
passed a constant value in each of them.  My theory is that in test1 gcc does a
const-eval of the isnan outside of the test function scope, whereas in the
other two it inlined isnan first and then optimized the constants within the
scope of the attribute.  Anyway this is just an example that the relationship
between the optimize attribute and inlined functions may be hard to predict (at
least, for people who aren't gcc maintainers ;))

#include <cmath>
#include <limits>
#include <cstdio>

void test1() __attribute__((optimize("fast-math")));
void test1() {
    const float n = std::numeric_limits<float>::quiet_NaN();
    printf("%d\n",std::isnan(n));
}

void test2() __attribute__((optimize("fast-math")));
void test2() {
    static const float n = std::numeric_limits<float>::quiet_NaN();
    printf("%d\n",std::isnan(n));
}

const float n = std::numeric_limits<float>::quiet_NaN();
void test3() __attribute__((optimize("fast-math")));
void test3() {
    printf("%d\n",std::isnan(n));
}

int main(int argc, char** argv) {
    test1(); test2(); test3(); return 0;
}

Output:
ejt@vbox-ubuntu-11:~$ g++ test.cc -o test -Wall -g -O3 && ./test
1
0
0
ejt@vbox-ubuntu-11:~$ nm test | c++filt | grep -i isnan
ejt@vbox-ubuntu-11:~$ g++ test.cc -o test -Wall -g -O0 && ./test
1
1
1
ejt@vbox-ubuntu-11:~$ nm test | c++filt | grep -i isnan
000000000040073a W __gnu_cxx::__enable_if<std::__is_arithmetic<float>::__value,
int>::__type std::isnan<float>(float)

Reply via email to