From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 32238 invoked by alias); 19 Apr 2002 18:36:15 -0000 Mailing-List: contact gcc-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-prs-owner@gcc.gnu.org Received: (qmail 32150 invoked by uid 71); 19 Apr 2002 18:36:08 -0000 Resent-Date: 19 Apr 2002 18:36:08 -0000 Resent-Message-ID: <20020419183608.32149.qmail@sources.redhat.com> Resent-From: gcc-gnats@gcc.gnu.org (GNATS Filer) Resent-To: nobody@gcc.gnu.org Resent-Cc: gcc-prs@gcc.gnu.org, gcc-bugs@gcc.gnu.org Resent-Reply-To: gcc-gnats@gcc.gnu.org, charles@Provis.com Received:(qmail 30226 invoked from network); 19 Apr 2002 18:30:32 -0000 Received: from unknown (HELO stroke.provis.com) (206.196.33.19) by sources.redhat.com with SMTP; 19 Apr 2002 18:30:32 -0000 Received: from dog.provis.com (dog.provis.com [206.196.33.73]) by stroke.provis.com (8.9.1/8.9.1) with ESMTP id NAA26881; Fri, 19 Apr 2002 13:30:04 -0500 (CDT) Received: (from charles@localhost) by dog.provis.com (8.10.2+Sun/8.10.2) id g3JIU2C08709; Fri, 19 Apr 2002 13:30:02 -0500 (CDT) Message-Id:<200204191830.g3JIU2C08709@dog.provis.com> Date: Fri, 19 Apr 2002 11:36:00 -0000 From: charles@Provis.com Reply-To: charles@Provis.com To: gcc-gnats@gcc.gnu.org Cc: sms@provis.com X-Send-Pr-Version:3.113 Subject: optimization/6377: Bitfield and Optimizer 2.96 and later, multi-platform X-SW-Source: 2002-04/txt/msg00985.txt.bz2 List-Id: >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: