Bug Report

Nadezhda I. Viyukova niva@niisi.msk.ru
Tue Nov 30 23:39:00 GMT 1999


Bug Report
==========
1. GCC version: 2.95.1.

2. Native compiler configured for sparc-sun-solaris as follows:

/gnu/niva/src/gcc-2.95.1/configure  \
            --target=sparc-sun-solaris2.6 \
            --host=sparc-sun-solaris2.6 \
            --build=sparc-sun-solaris2.6 \
            --prefix=/gnu/niva/local \
            --exec-prefix=/gnu/niva/local/H-sun \
            --enable-haifa \
            --verbose

3. Trouble: the compiler generates an enormous frame buffer
for a function using structures.

The function was compiled with the following command line

   gcc -O2 -S cmpl22.c -o cmpl22.s

The source codes are:

/* ------------ File cmpl22.c ---------------*/
#include "complex.h"

void cmpl22 (complex A[2][2], complex B[2][2], complex c[2][2])
  {
    c[0][0] = cadd(cmul(A[0][0], B[0][0]), cmul(A[0][1], B[1][0]));
    c[0][1] = cadd(cmul(A[0][0], B[0][1]), cmul(A[0][1], B[1][1]));
    c[1][0] = cadd(cmul(A[1][0], B[0][0]), cmul(A[1][1], B[1][0]));
    c[1][1] = cadd(cmul(A[1][0], B[0][1]), cmul(A[1][1], B[1][1]));
  }

/* -------------------- file complex.h ---------------------- */
#ifndef _my_complex_
#define _my_complex_ 1

#include "zaplat.h"

#ifdef HAVE_COMPLEX

static inline float __attribute__ ((const)) cabs (complex float a)
  { return real(a) * real(a) + imag(a) * imag(a); }
static inline float complex __attribute__ ((const)) cadd (float complex a, float complex b)
  {    return a+b;  }
static inline float complex __attribute__ ((const)) cmul (float complex a, float complex b)
  {    return a*b;  }
static inline float complex __attribute__ ((const)) csub (float complex a, float complex b)
  {    return a-b;  }
static inline float complex __attribute__ ((const)) cmul_fast (float complex a, float complex b)
  {    return a*b;  }
static inline float complex __attribute__ ((const)) cdiv (float complex a, float complex b)
  {    return a/b;  }

#else

typedef struct {float __attribute__ ((aligned (1)))  r; float __attribute__ ((aligned (1))) i;} __attribute__ ((aligned (1))) complex;

#ifndef NO_INLINE

static inline float __attribute__ ((const)) cabs (complex a) { return a.r * a.r + a.i * a.i; }

static inline complex __attribute__ ((const)) cadd (complex a, complex b)
  {
    register complex tmp = {a.r + b.r, a.i + b.i};
    return tmp;
  }

static inline complex __attribute__ ((const)) cmul (complex a, complex b)
  {
    register complex tmp = {a.r * b.r - a.i * b.i, a.r * b.i + a.i * b.r};
    return tmp;
  }

static inline complex __attribute__ ((const)) csub (complex a, complex b)
  {
    register complex tmp = {a.r - b.r, a.i - b.i};
    return tmp;
  }

static inline complex __attribute__ ((const)) cmul_fast (complex a, complex b)
  {
    register complex tmp;
    register float t = (b.r + b.i) * a.r;
    tmp.r = t - b.i * (a.r + a.i);
    tmp.i = t + b.r * (a.i - a.r);
    return tmp;
  }

static inline complex __attribute__ ((const)) cdiv (complex a, complex b)
  {
    register complex tmp;
    register float tmpr = a.r * b.r + a.i * b.i, tmpi = a.i * b.r - a.r * b.i;
    register float bbs = b.r * b.r + b.i * b.i;
    tmp.r = tmpr*inv(bbs); tmp.i = tmpi*inv(bbs);
    return tmp;
  }

#else

#ifndef NO_COPY

#define cabs(a)  \
  ({             \
    register complex ta = (a); \
    register float tar=ta.r, tai=ta.i; \
    tar * tar + tai * tai;                                    \
  })

#define cadd(a,b)  \
  ({               \
    register complex ta = (a), tb = (b); \
    register float tar=ta.r, tbr=tb.r, tai=ta.i, tbi=tb.i; \
    register complex tmp = {tar + tbr, tai + tbi}; \
    tmp;                                    \
  })

#define cmul(a,b) \
  ({              \
    register complex ta = (a), tb = (b); \
    register float tar=ta.r, tbr=tb.r, tai=ta.i, tbi=tb.i; \
    register complex tmp =           \
            {tar * tbr - tai * tbi, tar * tbi + tai * tbr}; \
    tmp;                                                            \
  })

#define csub(a,b) \
  ({              \
    register complex ta = (a), tb = (b); \
    register float tar=ta.r, tbr=tb.r, tai=ta.i, tbi=tb.i; \
    register complex tmp = {tar - tbr, tai - tbi}; \
    tmp;                                    \
  })

#define cmul_fast(a,b) \
  ({                   \
    register complex ta = (a), tb = (b); \
    register float tar=ta.r, tbr=tb.r, tai=ta.i, tbi=tb.i; \
    register complex tmp;                 \
    register float t = (tbr + tbi) * tar; \
    tmp.r = t - tbi * (tar + tai);        \
    tmp.i = t + tbr * (tai - tar);        \
    tmp;                           \
  })

#define cdiv(a,b)       \
  ({                    \
    register complex tmp;                 \
    register complex ta = (a), tb = (b); \
    register float tar=ta.r, tbr=tb.r, tai=ta.i, tbi=tb.i; \
    register float tmpr = tar * tbr + tai * tbi, tmpi = tai * tbr - tar * tbi; \
    register float bbs = tbr * tbr + tbi * tbi;                        \
    tmp.r = tmpr*inv(bbs); tmp.i = tmpi*inv(bbs);                                            \
    tmp;                                                                   \
  })

#else

#define cabs(a) ((a).r * (a).r + (a).i * (a).i)

#define cadd(a,b)  \
  ({               \
    register complex tmp = {a.r + b.r, a.i + b.i}; \
    tmp;                                    \
  })

#define cmul(a,b) \
  ({              \
    register complex tmp =           \
            {a.r * b.r - a.i * b.i, a.r * b.i + a.i * b.r}; \
    tmp;                                                            \
  })

#define csub(a,b) \
  ({              \
    register complex tmp = {a.r - b.r, a.i - b.i}; \
    tmp;                                    \
  })

#define cmul_fast(a,b) \
  ({                   \
    register complex tmp;                 \
    register float t = (b.r + b.i) * a.r; \
    tmp.r = t - b.i * (a.r + a.i);        \
    tmp.i = t + b.r * (a.i - a.r);        \
    tmp;                           \
  })

#define cdiv(a,b)       \
  ({                    \
    register complex tmp = {a.r * b.r + a.i * b.i, a.i * b.r - a.r * b.i}; \
    register float bbs = b.r * b.r + b.i * b.i;                        \
    tmp.r *= inv(bbs); tmp.i *= inv(bbs);                                            \
    tmp;                                                                   \
  })

#endif /* NO_COPY */

#endif /* NO_INLINE */

#endif /* HAVE_COMPLEX */

#endif /* _my_complex_*/

/* ------------ File zaplat.h ---------------*/
#ifndef _my_zaplat_
#define _my_zaplat_ 1

#ifdef NO_DIV
#ifndef SEED
float inv __attribute__ ((const)) (float);
#else
inline static float __attribute__ ((const)) inv (float x)
{
   register float res;
   asm ("fseedd %1,%0":"=f"(res):"f"(x));
   return res;
}
#endif
#else
#define inv(x) (1/(x))
#endif

#ifdef NO_SQRT
float __attribute__ ((const)) sQrT (float);
#define sqrt(x) (sQrT(x))
#endif

#ifdef SEED
inline static float __attribute__ ((const)) sqrt (float x)
{
   register float res;
   asm ("fseedr %1,%0":"=f"(res):"f"(x));
   return res;
}
#endif

#ifdef NO_ABS
static inline float __attribute__ ((const)) abs (float a)
              { return a<0.0 ? -a : a; }
#endif

#ifdef COMPLEX_PROBLEM
#define complex not_real
#endif

#endif /* _my_zaplat_*/

/* ------------------- End of source files ----------------- */



4. This (the trouble) was not the case with gcc-2.8.1.


5. We have worked around the trouble by making the following
change in the file gcc/function.c (function "assign_stack_temp_for_type"):

*** function.c  Fri May 21 02:26:35 1999
--- function.c.new      Mon Nov 15 17:53:47 1999
***************
*** 1032,1038 ****
        abort();
        p->slot = assign_stack_local (mode,
                                    mode == BLKmode
!                                     ? CEIL_ROUND (size, align) : size,
                                    align);

        p->align = align;
--- 1032,1038 ----
        abort();
        p->slot = assign_stack_local (mode,
                                    mode == BLKmode
!                                     ? CEIL_ROUND (size, align / BITS_PER_UNIT) : size,
                                    align);

        p->align = align;



More information about the Gcc-bugs mailing list