public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
From: charles@Provis.com
To: gcc-gnats@gcc.gnu.org
Cc: sms@provis.com
Subject: optimization/6377: Bitfield and Optimizer 2.96 and later, multi-platform
Date: Fri, 19 Apr 2002 11:36:00 -0000	[thread overview]
Message-ID: <200204191830.g3JIU2C08709@dog.provis.com> (raw)


>Number:         6377
>Category:       optimization
>Synopsis:       Optimization (>= -O2) with bitfields yields incorrect result
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          wrong-code
>Submitter-Id:   net
>Arrival-Date:   Fri Apr 19 11:36:07 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Charles Rennolet
>Release:        3.0.3
>Organization:
Provis Corporation
>Environment:
System: SunOS dog 5.8 Generic_108528-12 sun4u sparc SUNW,Sun-Blade-100
Architecture: sun4

	
host: sparc-sun-solaris2.8
build: sparc-sun-solaris2.8
target: sparc-sun-solaris2.8
configured with: ../gcc-3.0.3/configure 
>Description:
   gcc versions 2.96 and later have a problem with bitfields
and optimization.  There appears to be a mismatch between where the
results are left and where they should go, especially when there
is an intermediate cast.  The result is that the bitfield structure
is left with random data in it.  This happens on Solaris (with 3.0.3)
and Linux (with 2.96, 3.0.3, and 3.0.4) using optimization levels -O2
or higher.

>How-To-Repeat:
/* 
To Repeat: save this example program (self-contained
except for the printf at the bottom) and compile with -O3.  The
result should contain nonzero bits, but doesn't.  (The problem is
that the result in the getFoo is being put in the stack frame, while
the calling program expects the result in edx:eax.)

Charles Rennolet (charles@provis.com, clr@thurse.mn.org)

Example: (A very short one.)
*/
typedef struct
{
    unsigned int   device   : 28;
    unsigned int   stuckat  : 2;
    unsigned int   direction: 2;
    unsigned int   pin      : 12;
    unsigned int   port     : 12;
    unsigned int   status   : 4;
    unsigned int   type     : 4;
} *pFoo;

unsigned long long getFoo(int type,
                     int device,
                     int port,
                     int pin,
                     int InOut,
                     int stuckat)
{
    unsigned long long retValue = 0;

    ((pFoo)&retValue)->status    = 0;
    ((pFoo)&retValue)->type      = type;
    ((pFoo)&retValue)->device    = device;
    ((pFoo)&retValue)->port      = port;
    ((pFoo)&retValue)->pin       = pin;
    ((pFoo)&retValue)->direction = InOut;
    ((pFoo)&retValue)->stuckat   = stuckat;
    return(retValue);
}

int main( int argc, char **argv)
{
    unsigned long long foo;
    unsigned int one = 1;
    unsigned int two = 2;
    unsigned int three = 3;
    unsigned int four = 4;
    unsigned int five = 5;
    unsigned int six = 6;
    unsigned int seven = 7;
    unsigned int tmp;

    foo = getFoo( one, two, three, four, five, six);

    printf("foo = %016llx\n", foo);
}

/* ============================Example Ends============================= */

Preprocessed input file:

# 22 "foo.c"
typedef struct
{
    unsigned int device : 28;
    unsigned int stuckat : 2;
    unsigned int direction: 2;
    unsigned int pin : 12;
    unsigned int port : 12;
    unsigned int status : 4;
    unsigned int type : 4;
} *pFoo;

unsigned long long getFoo(int type,
                     int device,
                     int port,
                     int pin,
                     int InOut,
                     int stuckat)
{
    unsigned long long retValue = 0;

    ((pFoo)&retValue)->status = 0;
    ((pFoo)&retValue)->type = type;
    ((pFoo)&retValue)->device = device;
    ((pFoo)&retValue)->port = port;
    ((pFoo)&retValue)->pin = pin;
    ((pFoo)&retValue)->direction = InOut;
    ((pFoo)&retValue)->stuckat = stuckat;
    return(retValue);
}

int main( int argc, char **argv)
{
    unsigned long long foo;
    unsigned int one = 1;
    unsigned int two = 2;
    unsigned int three = 3;
    unsigned int four = 4;
    unsigned int five = 5;
    unsigned int six = 6;
    unsigned int seven = 7;
    unsigned int tmp;

    foo = getFoo( one, two, three, four, five, six);

    printf("foo = %016llx\n", foo);
}
>Fix:
	Don't compile with -O2 or greater?  Yeah, I know it's lame.


>Release-Note:
>Audit-Trail:
>Unformatted:


                 reply	other threads:[~2002-04-19 18:36 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200204191830.g3JIU2C08709@dog.provis.com \
    --to=charles@provis.com \
    --cc=gcc-gnats@gcc.gnu.org \
    --cc=sms@provis.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).