https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67032
Bug ID: 67032
Summary: Geode optimizations incorrectly return -NaN
Product: gcc
Version: 5.1.0
Status: UNCONFIRMED
Severity: major
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: joshkel at gmail dot com
Target Milestone: ---
When optimizing for the Geode architecture (-O2 -march=geode), functions may
incorrectly return -NaN instead of the expected result.
Here's a test case. (I apologize for its length; most of my attempts to shorten
it cause the bug to not manifest.)
/* main.cpp */
#include "Statistic.h"
#include <iostream>
void acquire_data()
{
Statistic stat;
stat.Accumulate(0);
stat.Accumulate(0);
std::cout << stat.Var() << std::endl;
std::cout << stat.StdDev() << std::endl;
}
int main(int, char**)
{
acquire_data();
}
/* Statistic.h */
#define STATISTICH
#include <cmath>
#include <cstdio>
#define MY_ASSERT(expr) ((expr) ? (0): std::puts(#expr))
class Statistic
{
public:
Statistic() : mCount(0), mSum(0), mSumSquared(0) {}
void Accumulate(int val);
double Var() const { MY_ASSERT(mCount > 0); return mCount == 1 ? 0 :
(mSumSquared - mSum * mSum / mCount) / (mCount - 1); }
double StdDev() const { if (Var() < 0.00000001) return 0; else return
std::sqrt(Var()); }
private:
unsigned mCount;
double mSum, mSumSquared;
};
#endif
/* Statistic.cpp */
#include "Statistic.h"
void Statistic::Accumulate(int val)
{
mCount++;
mSum += val;
mSumSquared += double(val) * double(val);
}
The expected output is
0
0
However, when compiled with -O2 -march=geode, the output is
0
-nan
I can reproduce this bug in Ubuntu's g++ 4.9.2 and 5.1.0 and a from-source g++
5.1.0, but not in Ubuntu's g++ 4.8.4 or 4.6.4 or a from-source g++ 4.6.4.