optimization/4733: Incorrect code when aliasing double and struct on ARM -O2
bjh21@netbsd.org
bjh21@netbsd.org
Mon Oct 29 09:26:00 GMT 2001
>Number: 4733
>Category: optimization
>Synopsis: Incorrect code when aliasing double and struct on ARM -O2
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: wrong-code
>Submitter-Id: net
>Arrival-Date: Mon Oct 29 09:26:00 PST 2001
>Closed-Date:
>Last-Modified:
>Originator: Ben Harris
>Release: 3.1 20011023 (experimental)
>Organization:
The NetBSD Project
>Environment:
System: Linux wraith 2.4.12 #13 Mon Oct 29 11:21:47 GMT 2001 i686 unknown
Architecture: i686
host: i686-pc-linux-gnu
build: i686-pc-linux-gnu
target: arm-unknown-elf
configured with: ./configure --target=arm-unknown-elf
>Description:
Compiling the code below with -O2 generates, at the start of the function:
sub sp, sp, #8
mov r2, #2032
ldrh r3, [sp, #6] @ movhi
add r2, r2, #15
and r3, r2, r3, lsr #4
cmp r3, r2
stmia sp, {r0-r1}
As far as I can see, this allocates eight bytes of stack, loads from
it (ldrh), messes around a bit and then stores the value it was
expecting to load (stmia). Obviously the stmia shouldn't have been
moved to after the ldrh. This problem also exists in GCC 3.0.1 and
the NetBSD version of GCC 2.95.3 (where I first found it).
>How-To-Repeat:
use "./cc1 -O2"
typedef unsigned int u_int;
struct ieee_double {
u_int dbl_fracl;
u_int dbl_frach:20;
u_int dbl_exp:11;
u_int dbl_sign:1;
};
int
isinf (d)
double d;
{
register struct ieee_double *p = (struct ieee_double *)(void *)&d;
return (p->dbl_exp == 2047 &&
(p->dbl_frach == 0 && p->dbl_fracl == 0));
}
>Fix:
-fno-schedule-insns -fno-schedule-insns2 causes the problem to go away.
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the Gcc-prs
mailing list