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