From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21600 invoked by alias); 1 Aug 2002 12:46:10 -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 21566 invoked by uid 71); 1 Aug 2002 12:46:07 -0000 Resent-Date: 1 Aug 2002 12:46:07 -0000 Resent-Message-ID: <20020801124607.21564.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, eric.paire@ri.silicomp.fr Received: (qmail 21426 invoked from network); 1 Aug 2002 12:45:11 -0000 Received: from unknown (HELO mailhost.ri.silicomp.fr) (62.160.165.1) by sources.redhat.com with SMTP; 1 Aug 2002 12:45:11 -0000 Received: from ri.silicomp.fr (cheetah [62.160.165.103]) by mailhost.ri.silicomp.fr (8.12.1/8.12.1) with ESMTP id g71Clerr003507 for ; Thu, 1 Aug 2002 14:47:40 +0200 Received: (from paire@localhost) by ri.silicomp.fr (8.11.6/8.8.7) id g71CldE12727; Thu, 1 Aug 2002 14:47:39 +0200 Message-Id: <200208011247.g71CldE12727@ri.silicomp.fr> Date: Thu, 01 Aug 2002 05:46:00 -0000 From: eric.paire@ri.silicomp.fr Reply-To: eric.paire@ri.silicomp.fr To: gcc-gnats@gcc.gnu.org X-Send-Pr-Version: 3.113 Subject: optimization/7465: Same function produces bad ARM code with C++ but correct one with C X-SW-Source: 2002-08/txt/msg00002.txt.bz2 List-Id: >Number: 7465 >Category: optimization >Synopsis: Same function produced bad ARM code with C++ but correct one with C >Confidential: no >Severity: serious >Priority: medium >Responsible: unassigned >State: open >Class: wrong-code >Submitter-Id: net >Arrival-Date: Thu Aug 01 05:46:06 PDT 2002 >Closed-Date: >Last-Modified: >Originator: Eric PAIRE >Release: 3.1.1 >Organization: Silicomp Research Institute >Environment: System: Linux cheetah.ri.silicomp.com 2.4.7-10 #1 Thu Sep 6 17:27:27 EDT 2001 i686 unknown Architecture: i686 host: i686-pc-linux-gnu build: i686-pc-linux-gnu target: arm-unknown-elf configured with: ../gnu_tools/gcc/configure --target=arm-elf --prefix=/home/paire/ecos/gcc-3.1.1+binutils-2.12.1-cross/ --with-stabs --with-gnu-as --with-gnu-ld --with-headers=/home/paire/ecos/build-at91-ecos/install/include --with-libs=/home/paire/ecos/build-at91-ecos/install/lib --enable-languages=c,c++ --disable-nls >Description: With the same input code, GCC generates wrong ARM code when used with the C++ front-end, but correct one when used with the C front-end. Although visible with the ARM back-end, it seems to be completely independent from it and only related to the instruction scheduler. I have made a short investigation, and it seems that the only difference between the RTL generated by the C and the one generated by the C++ is in the alias set computation. I have written a short program that shows up the problem (unfortunately, only visible by people familiar with the ARM assembler). >How-To-Repeat: The same program can be named foo.c and foo.cc (in order to activate the two front-ends). The problem is that the "obj" value dereferenced to get the "next_element" field has been overwritten by "gs.last_element" instead of being kept from the the original "h" value. ------ Cut Here ------ Cut Here ------ Cut Here ------ Cut Here ------ typedef struct object { struct object *next_element; } object; struct globals { void *last_element; } gs; void free_obj(object *h); void free_ptr(void *h) { object *obj = *(object **)h; *(void **)h = gs.last_element; gs.last_element = h; free_obj(obj->next_element); // The value of "obj" is incorrect with C++ } ------ Cut Here ------ Cut Here ------ Cut Here ------ Cut Here ------ when generated with the C front-end: 00000000 : 0: e92d4010 stmdb sp!, {r4, lr} 4: e59f401c ldr r4, [pc, #28] ; 28 8: e5903000 ldr r3, [r0] c: e1a01000 mov r1, r0 10: e5942000 ldr r2, [r4] 14: e5930000 ldr r0, [r3] 18: e5812000 str r2, [r1] 1c: e5841000 str r1, [r4] 20: e8bd4010 ldmia sp!, {r4, lr} 24: eafffffe b 0 24: R_ARM_PC24 free_obj 28: 00000000 andeq r0, r0, r0 28: R_ARM_ABS32 gs Notice that at offset 8, "obj" is kept in r3 and that at offset 14, r0 contains the right "obj->next_element". BUT, when generated with the C++ front-end 00000000 <_Z8free_ptrPv>: 0: e52de004 str lr, [sp, -#4]! 4: e59f1014 ldr r1, [pc, #20] ; 20 <_Z8free_ptrPv+0x20> 8: e5913000 ldr r3, [r1] c: e5803000 str r3, [r0] 10: e5810000 str r0, [r1] 14: e5930000 ldr r0, [r3] 18: e49de004 ldr lr, [sp], #4 1c: eafffffe b 0 <_Z8free_ptrPv> 1c: R_ARM_PC24 _Z8free_objP6object 20: 00000000 andeq r0, r0, r0 20: R_ARM_ABS32 gs Notice that "obj" is not kept, but instead at line c, "obj" is overwritten with r3 containing "gs.last_element", thus leading to the bug that the "obj->next_element" is in fact "gs.last_element". >Fix: The (temporary) fix for the C++ front-end (since the C front-end works correctly) is to modify the code to help the front-end to detect aliasing: Replace *(void **)h = gs.last_element; by *(object **)h = (object *)gs.last_element; >Release-Note: >Audit-Trail: >Unformatted: