This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
c/5315: Incorrect loads in FP compare code on i686
- From: pbarada at mail dot wm dot sps dot mot dot com
- To: gcc-gnats at gcc dot gnu dot org
- Date: Tue, 8 Jan 2002 17:00:19 -0500
- Subject: c/5315: Incorrect loads in FP compare code on i686
>Number: 5315
>Category: c
>Synopsis: Incorrect loads in FP compare code on i686
>Confidential: no
>Severity: critical
>Priority: medium
>Responsible: unassigned
>State: open
>Class: wrong-code
>Submitter-Id: net
>Arrival-Date: Tue Jan 08 14:06:01 PST 2002
>Closed-Date:
>Last-Modified:
>Originator: Peter Barada
>Release: 3.0.3 20011213 (prerelease)
>Organization:
Motorola, Inc.
>Environment:
System: Linux hyper.wm.sps.mot.com 2.4.2-2 #1 Sun Apr 8 20:41:30 EDT 2001 i686 unknown
Architecture: i686
host: i686-pc-linux-gnu
build: i686-pc-linux-gnu
target: i686-pc-linux-gnu
configured with: /home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-3.0.3-20011213/configure --target=i686-linux --prefix=/tmp/crap8 --enable-languages=c --with-local-prefix=/tmp/crap8/i686-linux --with-newlib --disable-shared : (reconfigured) /home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-3.0.3-20011213/configure --with-gcc-version-trigger=/home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-3.0.3-20011213/gcc/version.c --host=i686-pc-linux-gnu --target=i686-linux --prefix=/tmp/crap8 --enable-languages=c --with-local-prefix=/tmp/crap8/i686-linux --with-newlib --disable-shared
>Description:
Compile the test code with "-S -msoft-float -g -dp" options.
The code when compiled without optimization loads the same value(insn
32, insn 35) onto the stack twice before calling __gtsf2 which
prevents the else clause from ever being taken. code generated looks like:
interln:
.LFB1:
.LM1:
.LBB2:
.LBB3:
pushl %ebp # 86 *pushsi2 [length = 1]
.LCFI0:
movl %esp, %ebp # 88 *movsi_1/2 [length = 2]
.LCFI1:
subl $24, %esp # 90 *pro_epilogue_adjust_stack_1/1 [length = 3]
.LCFI2:
.LM2:
movl 12(%ebp), %eax # 12 *movsf_1/4 [length = 3]
movl %eax, -8(%ebp) # 14 *movsf_1/5 [length = 3]
leal -8(%ebp), %eax # 76 *lea_1 [length = 2]
andl $2147483647, (%eax) # 16 *andsi_1/1 [length = 6]
.LBE3:
.LBB4:
movl 8(%ebp), %eax # 23 *movsf_1/4 [length = 3]
movl %eax, -8(%ebp) # 25 *movsf_1/5 [length = 3]
leal -8(%ebp), %eax # 78 *lea_1 [length = 2]
andl $2147483647, (%eax) # 27 *andsi_1/1 [length = 6]
.LBE4:
movl -8(%ebp), %eax # 32 *movsf_1/4 [length = 3]
movl %eax, (%esp) # 33 *movsf_1/5 [length = 3]
movl -8(%ebp), %eax # 35 *movsf_1/4 [length = 3]
movl %eax, 4(%esp) # 36 *movsf_1/5 [length = 3]
call __gtsf2 # 37 *call_value_0 [length = 6]
Note that insn 32 and 35 load the same value onto the stack. Backing
up further, notice that insns 76/16 and insns 78/27 store the result of
the absolute value for each side of the '>' expression into the same
location (-8(%ebp)). If compiled with '-O', this problem does not
exhibit itself.
>How-To-Repeat:
#define FFABS(x) ({ \
union {float f; unsigned int l;} z; \
z.f = (float)(x); \
z.l &= 0x7fffffff; \
z.f; \
})
typedef float real;
typedef struct {
real x,y;
} Point;
extern void foo(real, real);
extern void bar(real, real);
void interln (real bdx, real bdy)
{
real c2;
if (FFABS(bdy) > FFABS(bdx)) {
foo(bdx, bdy);
}
else {
bar(bdy, bdx);
}
}
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted: