On Sat, Jan 19, 2013 at 2:12 PM, Steven Bosscher wrote:
> It looks like this merge breaks bootstrap on
> powerpc64-unknown-linux-gnu. The compiler goes into an infinite loop
> while compiling libdecnumber. I'm trying to create a small test case.

Here it is. Compile with:

$ ./cc1 -quiet -mlong-double-128 -mno-minimal-toc -g -O2 -fPIC
-fbuilding-libgcc -fno-stack-protector lra_ppc64_infloop.c

I haven't looked into the problem much, but it looks like some kind of
reloading problem: max_reg_num() keeps growing until OOM.

Ciao!
Steven


typedef int int8_t __attribute__ ((__mode__ (__QI__)));
typedef int int16_t __attribute__ ((__mode__ (__HI__)));
typedef int int32_t __attribute__ ((__mode__ (__SI__)));
typedef unsigned int uint8_t __attribute__ ((__mode__ (__QI__)));
typedef unsigned int uint16_t __attribute__ ((__mode__ (__HI__)));
typedef unsigned int uint32_t __attribute__ ((__mode__ (__SI__)));

enum
{
  FE_INEXACT = 1 << (31 - 6),
  FE_DIVBYZERO = 1 << (31 - 5),
  FE_UNDERFLOW = 1 << (31 - 4),
  FE_OVERFLOW = 1 << (31 - 3),
  FE_INVALID = 1 << (31 - 2),
};
enum rounding
{
  DEC_ROUND_CEILING,
  DEC_ROUND_UP,
  DEC_ROUND_HALF_UP,
  DEC_ROUND_HALF_EVEN,
  DEC_ROUND_HALF_DOWN,
  DEC_ROUND_DOWN,
  DEC_ROUND_FLOOR,
  DEC_ROUND_05UP,
  DEC_ROUND_MAX
};
typedef struct
{
  int32_t digits;
  int32_t emax;
  int32_t emin;
  enum rounding round;
  uint32_t traps;
  uint32_t status;
  uint8_t clamp;
} decContext;
typedef union
{
  uint8_t bytes[8];
  uint16_t shorts[8 / 2];
  uint32_t words[8 / 4];
} decDouble;
typedef union
{
  uint8_t bytes[4];
  uint16_t shorts[4 / 2];
  uint32_t words[4 / 4];
} decSingle;

typedef decDouble *(*dfp_binary_func)
  (decDouble *, const decDouble *, const decDouble *, decContext *);

extern enum rounding __decGetRound (void);
extern decDouble *__decSingleToWider (const decSingle *, decDouble *);
extern decContext *__decContextDefault (decContext *, int32_t);
extern decSingle *__decSingleFromWider (decSingle *, const decDouble *,
                                        decContext *);
void __dfp_raise_except (int);

extern decDouble dfp_binary_op (dfp_binary_func, decDouble, decDouble);

_Decimal32 d32_binary_op (dfp_binary_func, _Decimal32, _Decimal32);

_Decimal32 __attribute__((__noinline__,__noclone__))
d32_binary_op (dfp_binary_func op, _Decimal32 arg_a, _Decimal32 arg_b)
{
  union
  {
    _Decimal32 c;
    decSingle f;
  } a32, b32, res32;
  decDouble a, b, res;
  decContext context;
  a32.c = arg_a;
  b32.c = arg_b;
  __decSingleToWider (&a32.f, &a);
  __decSingleToWider (&b32.f, &b);
  res = dfp_binary_op (op, a, b);
  __decContextDefault (&context, 32);
  context.round = __decGetRound ();
  __decSingleFromWider (&res32.f, &res, &context);
  if (1 && context.status != 0)
    {
      int ieee_flags;
      int dec_flags = (0x00000020) | (0x00000200) | (0x00002000);
      dec_flags &= context.status;
      ieee_flags = __extension__ (
                                   {
                                   int _fe_flags = 0;
                                   if ((dec_flags & (0x00000002)) !=
                                       0) _fe_flags |= FE_DIVBYZERO;
                                   if ((dec_flags & (0x00000020)) !=
                                       0) _fe_flags |= FE_INEXACT;
                                   if ((dec_flags &
                                        (0x00000001 | 0x00000004 | 0x00000008
                                         | 0x00000010 | 0x00000040 |
                                         0x00000080)) != 0) _fe_flags |=
                                   FE_INVALID;
                                   if ((dec_flags & (0x00000200)) !=
                                       0) _fe_flags |= FE_OVERFLOW;
                                   if ((dec_flags & (0x00002000)) !=
                                       0) _fe_flags |= FE_UNDERFLOW;
                                   _fe_flags;}
      );
      if (ieee_flags != 0)
        __dfp_raise_except (ieee_flags);
    }
  return res32.c;
}

Reply via email to