This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
gcc 2.95.2/Cygwin/x86 floating point code generation bug
- To: <gcc-bugs at gcc dot gnu dot org>
- Subject: gcc 2.95.2/Cygwin/x86 floating point code generation bug
- From: "Mathew Hendry" <scampi at dial dot pipex dot com>
- Date: Mon, 21 Feb 2000 22:42:01 -0000
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