Date: Fri, 11 May 2001 15:29:09 +0400 (MSD) From: "Igor Yu. Zhbanov" To: pgcc AT delorie DOT com Subject: Assembly code generation bug in pgcc-1.1.3. Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Reply-To: pgcc AT delorie DOT com Hello! I have found a bug in pgcc-1.1.3 compiler. "pgcc -v" reports: Reading specs from /usr/lib/gcc-lib/i586-pc-linux-gnu/pgcc-2.91.66/specs gcc version pgcc-2.91.66 19990314 (egcs-1.1.2 release) My system is: linux-2.2.19; CPU: AMD-K6-II 450MHz; glibc-2.2 Here is the minimal test example exp.c: _____________________________________________________ #include int multiply_by2(int arg) { int result=arg*2; /* Uncomment the line below to get correct result. */ /* asm(""); */ if(result==0) result=arg; /* Why not? :) */ return result; } int main(void) { printf("5 x 2 = %d\n",multiply_by2(5)); return 0; } ----------------------------------------------------- How do you think what is the result of multiply_by2(5)? Ten? No, five! The compilation command is 'pgcc -O exp.c'. But you may also compile this file with '-O1' or with '-O2'. Here is the fragment of assembly output of 'pgcc -O -S exp.c'. ______'asm("");' line is commented_________'asm("");' line is not commented ___ | .file "exp.c" | .file "exp.c" .version "01.01" | .version "01.01" gcc2_compiled.: | gcc2_compiled.: .text | .text .globl multiply_by2 | .globl multiply_by2 .type multiply_by2,@function | .type multiply_by2,@function multiply_by2: | multiply_by2: pushl %ebp | pushl %ebp movl %esp,%ebp | movl %esp,%ebp movl 8(%ebp),%edx | movl 8(%ebp),%edx leal 0(,%edx,2),%eax | leal 0(,%edx,2),%eax | #APP | | #NO_APP | testl %eax,%eax jne .L17 | jne .L17 movl %edx,%eax | movl %edx,%eax .L17: | .L17: movl %ebp,%esp | movl %ebp,%esp popl %ebp | popl %ebp ret | ret ------------------------------------------------------------------------------ As you may see assembly text of function 'multiply_by2' in case of pgcc's bug, instruction 'testl %eax,%eax' is missed and since 'lea' instruction does not affect to any procesor's flags on Intel platforms, conditional jump 'jne .L17' can not be executed, so '5 x 2 = 5'. I have used 'asm("");' operator since it least affects the assembly output. P.S. I have found this bug during compilation of XFree86-3.3.6. When I have installed KDE-2.2.1 X server crashes after start. During debuging of Xserver with my favourite method (by inserting fprintf()) I have found out that after inserting fprintf() in one function of libfont.a X server starts normally. I was surprised. Cutting off all unnecessary I have written that small file. Thank you.