This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

gcc 2.95.2/Cygwin/x86 floating point code generation bug


Hi, little bug report for you. Found this while tracking down some bugs in
the LAME MP3 encoder.

Bug details
-----------

Compiler: gcc 2.95.2, compiled for Cygwin B20.1, but also known to appear
under Linux

Example input file: test.c (attached)

Example compiler output: test.s (attached)

Command line: gcc -O -g test.c -S

Machine: Celeron 400 running Windows 2000 Final

Bug description
---------------

When compiling the attached source, gcc generates code that loads garbage
onto the FP stack.
Referring to the attached compiler output, lines 59 and 60 read

  flds -8(%ebp)
  fldl -16(%ebp)

Neither of these stack locations have been initialised with valid floating
point data. This frequently triggers "invalid operation" FP exceptions when
executing the code.

-- Mat.

/* ---------------------------------------------------------------------- */
/* Various type/macro definitions from the original code */

#define SBPSY_l 21
#define SBPSY_s 12
#define SBMAX_l 22
#define SBMAX_s 13

#define Max(A, B) ((A) > (B) ? (A) : (B))

typedef struct {
  float l[SBPSY_l];
  float s[SBPSY_s][3];
} III_psy_xmin;

typedef struct {
  III_psy_xmin thm;
  III_psy_xmin en;
} III_psy_ratio;

typedef struct {
  unsigned part2_3_length;
  unsigned big_values;
  unsigned count1;
  unsigned global_gain;
  unsigned scalefac_compress;
  unsigned window_switching_flag;
  unsigned block_type;
  unsigned mixed_block_flag;
  unsigned table_select[3];
  int      subblock_gain[3];
  unsigned region0_count;
  unsigned region1_count;
  unsigned preflag;
  unsigned scalefac_scale;
  unsigned count1table_select;
  unsigned part2_length;
  unsigned sfb_lmax;
  unsigned sfb_smax;
  unsigned count1bits;
  unsigned *sfb_partition_table;
  unsigned slen[4];
} gr_info;

typedef struct
{
  int l[1+SBMAX_l];
  int s[1+SBMAX_s];
} scalefac_struct;

extern float ATH_l[SBPSY_l];
extern float ATH_s[SBPSY_l];
extern scalefac_struct scalefac_band;
extern float masking_lower;

/* ---------------------------------------------------------------------- */
/* A cut down version of the affected function */

int calc_xmin(float xr[576], III_psy_ratio *ratio,
              gr_info *cod_info, III_psy_xmin *l3_xmin) {
  int start, end, bw, sfb, l, b, ath_over=0;
  float en0=0, xmin=0, ener=0;

  for (sfb = 0; sfb < cod_info->sfb_lmax; sfb++){
    start = scalefac_band.l[sfb];
    end = scalefac_band.l[sfb+1];
    bw = end - start;

    for (en0 = 0.0, l = start; l < end; l++) {
      ener = xr[l] * xr[l];
      en0 += ener;
    }
    en0 /= bw;

    xmin = ratio->en.l[sfb];
    if (xmin > 0.0)
      xmin = en0 * ratio->thm.l[sfb] * masking_lower / xmin;

    l3_xmin->l[sfb]=Max(ATH_l[sfb], xmin);
    if (en0 > ATH_l[sfb])
      ath_over++;
  }

  return ath_over;
}

/* ---------------------------------------------------------------------- */
/* Assembly language output from gcc -O -fomit-frame-pointer test.c -S */

/*
	.file	"test.c"
gcc2_compiled.:
___gnu_compiled_c:
.text
	.align 4
.globl _calc_xmin
	.def	_calc_xmin;	.scl	2;	.type	32;	.endef
_calc_xmin:
	subl $28,%esp
	pushl %ebp
	pushl %edi
	pushl %esi
	pushl %ebx
	movl 48(%esp),%esi
	xorl %edi,%edi
	xorl %ebx,%ebx
	movl 56(%esp),%eax
	cmpl 80(%eax),%edi
	jae L4
	movl $_ATH_l,%ebp
	flds 24(%esp)       ; invalid load
	fldl 16(%esp)       ; invalid load
	flds _masking_lower
	.p2align 4,,7
L6:
	movl _scalefac_band(,%ebx,4),%eax
	movl _scalefac_band+4(,%ebx,4),%edx
	movl %edx,%ecx
	subl %eax,%ecx
	fldz
	cmpl %edx,%eax
	jge L8
	.p2align 4,,7
L10:
	flds (%esi,%eax,4)
	fmul %st(0),%st
	faddp %st,%st(1)
	incl %eax
	cmpl %edx,%eax
	jl L10
L8:
	movl %ecx,28(%esp)
	fildl 28(%esp)
	fdivrp %st,%st(1)
	leal 0(,%ebx,4),%ecx
	movl 52(%esp),%eax
	flds 228(%ecx,%eax)
	fldz
	fcomp %st(1)
	fnstsw %ax
	andb $69,%ah
	cmpb $1,%ah
	jne L12
	fld %st(1)
	movl 52(%esp),%eax
	fmuls (%ecx,%eax)
	fmul %st(3),%st
	fdivp %st,%st(1)
L12:
	leal 0(,%ebx,4),%ecx
	flds (%ecx,%ebp)
	fcom %st(1)
	fnstsw %ax
	andb $69,%ah
	je L18
	fstp %st(0)
	jmp L14
L18:
	fstp %st(1)
L14:
	movl 60(%esp),%eax
	fstps (%ecx,%eax)
	fcomps (%ebp,%ebx,4)
	fnstsw %ax
	andb $69,%ah
	jne L5
	incl %edi
L5:
	incl %ebx
	movl 56(%esp),%eax
	cmpl 80(%eax),%ebx
	jb L6
	fstp %st(0)
	fstpl 16(%esp)
	fstps 24(%esp)
L4:
	movl %edi,%eax
	popl %ebx
	popl %esi
	popl %edi
	popl %ebp
	addl $28,%esp
	ret
*/

test.s


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]