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.

Reply via email to