Bug 4733 - Incorrect code when aliasing double and struct on ARM -O2
Summary: Incorrect code when aliasing double and struct on ARM -O2
Status: RESOLVED DUPLICATE of bug 21920
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 3.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2001-10-29 09:26 UTC by bjh21
Modified: 2005-06-05 09:32 UTC (History)
3 users (show)

See Also:
Host: i686-pc-linux-gnu
Target: arm-unknown-elf
Build: i686-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description bjh21 2001-10-29 09:26:00 UTC
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).

Release:
3.1 20011023 (experimental)

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

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));
}
Comment 1 bjh21 2001-10-29 09:26:00 UTC
Fix:
-fno-schedule-insns -fno-schedule-insns2 causes the problem to go away.
Comment 2 Richard Earnshaw 2001-10-29 17:43:44 UTC
From: Richard Earnshaw <rearnsha@arm.com>
To: bjh21@netbsd.org
Cc: gcc-gnats@gcc.gnu.org, Richard.Earnshaw@arm.com
Subject: Re: optimization/4733: Incorrect code when aliasing double and 
 struct on ARM -O2
Date: Mon, 29 Oct 2001 17:43:44 +0000

 > >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));
 > }
 
 Nope, this code violates the ANSI memory aliasing rules.  According to 
 ANSI, the only way to do this portably is to memcpy between the types; gcc 
 will do the right thing if you use a union, but not otherwise.
 
 R.
 

Comment 3 bjh21 2001-10-29 18:08:14 UTC
From: Ben Harris <bjh21@netbsd.org>
To: <Richard.Earnshaw@arm.com>
Cc: <gcc-gnats@gcc.gnu.org>
Subject: Re: optimization/4733: Incorrect code when aliasing double and 
 struct on ARM -O2
Date: Mon, 29 Oct 2001 18:08:14 +0000 (GMT)

 On Mon, 29 Oct 2001, Richard Earnshaw wrote:
 
 > Nope, this code violates the ANSI memory aliasing rules.
 
 Ah yes, I'd tried -fno-strict-aliasing on 2.95.3, but not on 20011023.
 Thanks.
 
 >  According to
 > ANSI, the only way to do this portably is to memcpy between the types;
 
 Yeah, that works.  The code it produces isn't all that wonderful, though:
 
 	...
         mov     r3, sp
         stmia   r3, {r0-r1}
         ldmia   r3, {r0, r1}
         add     r2, sp, #8
         stmia   r2, {r0, r1}
         mov     r2, #2032
         ldrh    r3, [sp, #14]   @ movhi
 	...
 
 -- 
 Ben Harris                                                   <bjh21@netbsd.org>
 Portmaster, NetBSD/arm26               <URL:http://www.netbsd.org/Ports/arm26/>
 
 
Comment 4 Toon Moene 2002-02-04 13:29:02 UTC
State-Changed-From-To: open->closed
State-Changed-Why: User error.  The compiler is allowed to assume that the
    struct and the double aren't aliased.
    
    Use -fno-strict-aliasing if you want to compile this code
    with gcc.
Comment 5 Nathanael C. Nerode 2003-05-23 05:02:48 UTC
toggling to mark as duplicate of 4410
Comment 6 Nathanael C. Nerode 2003-05-23 05:03:06 UTC
oops
Comment 7 Nathanael C. Nerode 2003-05-23 15:37:24 UTC
...
Comment 8 Nathanael C. Nerode 2003-05-23 15:37:36 UTC
.
Comment 9 Andrew Pinski 2005-06-05 09:32:36 UTC
Reopening to ...
Comment 10 Andrew Pinski 2005-06-05 09:32:53 UTC
Mark as a dup of bug 21920.

*** This bug has been marked as a duplicate of 21920 ***