public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
From: eric.paire@ri.silicomp.fr
To: gcc-gnats@gcc.gnu.org
Subject: optimization/7465: Same function produces bad ARM code with C++ but correct one with C
Date: Thu, 01 Aug 2002 05:46:00 -0000	[thread overview]
Message-ID: <200208011247.g71CldE12727@ri.silicomp.fr> (raw)


>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 <free_ptr>:
   0:   e92d4010        stmdb   sp!, {r4, lr}
   4:   e59f401c        ldr     r4, [pc, #28]   ; 28 <free_ptr+0x28>
   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 <free_ptr>
                        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:


                 reply	other threads:[~2002-08-01 12:46 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=200208011247.g71CldE12727@ri.silicomp.fr \
    --to=eric.paire@ri.silicomp.fr \
    --cc=gcc-gnats@gcc.gnu.org \
    /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).