Bug 61931 - gcc -O2 -fPIC -march=i686 -mcpu=i686 generates wrong code
Summary: gcc -O2 -fPIC -march=i686 -mcpu=i686 generates wrong code
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Linux
Classification: Retired
Component: gcc   
(Show other bugs)
Version: 7.3
Hardware: i386 Linux
medium
medium
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact:
URL:
Whiteboard:
Keywords:
Depends On:
Blocks: 61590
TreeView+ depends on / blocked
 
Reported: 2002-03-26 01:03 UTC by hjl
Modified: 2008-05-01 15:38 UTC (History)
0 users

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2002-03-27 18:24:10 UTC
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
A testcase in C++ (108.87 KB, text/plain)
2002-03-26 01:04 UTC, hjl
no flags Details
A patch back ported from gcc 3.1 (6.61 KB, patch)
2002-03-26 02:48 UTC, hjl
no flags Details | Diff
A simple testcase in C. (517 bytes, application/octet-stream)
2002-03-26 09:47 UTC, hjl
no flags Details


External Trackers
Tracker ID Priority Status Summary Last Updated
Red Hat Product Errata RHBA-2002:055 contract SHIPPED_LIVE Updated version of GCC 2.96-RH now available 2002-04-02 05:00:00 UTC

Description hjl 2002-03-26 01:03:38 UTC
# gcc -O2 -fPIC -march=i686 -mcpu=i686 ft_ID_Key.ii -S

generates wrong code.  The problem is gcc emits:

        .section        .gnu.linkonce.t._._9ft_ID_Key,"ax",@progbits
        .align 16
.LPR0:
        movl    (%esp), %ebx
        ret
        .weak   _._9ft_ID_Key
        .type    _._9ft_ID_Key,@function
_._9ft_ID_Key:
.LFB1:
        pushl   %ebp
.LCFI0:
        movl    %esp, %ebp
.LCFI1:
        pushl   %edi
.LCFI2:
        pushl   %esi
.LCFI3:
        pushl   %ebx
.LCFI4:
        subl    $20, %esp
.LCFI5:
        call    .LPR0
...
        .section        .gnu.linkonce.t.__tf9ft_ID_Key,"ax",@progbits
        .align 16
        .weak   __tf9ft_ID_Key
        .type    __tf9ft_ID_Key,@function
__tf9ft_ID_Key:  
.LFB2:
        pushl   %ebp
.LCFI7:
        movl    %esp, %ebp
.LCFI8:
        pushl   %esi
.LCFI9:
        pushl   %ebx
.LCFI10:
        call    .LPR0

That is instead of generating

.LPR0:
        movl    (%esp), %ebx
        ret

for each function in the linkonce section, gcc uses one

.LPR0:
        movl    (%esp), %ebx
        ret

in a linkonce section for the whole file. But the linker may discard
that linkonce section where the .LPR0 code is in in the final binary.
As the result, the current link will complain

        call    .LPR0

with something like

warning: relocation against removed section ...

and keep going. They will be turned into something like "call 0".

Comment 1 hjl 2002-03-26 01:04:25 UTC
Created attachment 50364 [details]
A testcase in C++

Comment 2 hjl 2002-03-26 01:04:55 UTC
BTW, gcc 3.1 is ok.

Comment 3 hjl 2002-03-26 02:48:14 UTC
Created attachment 50384 [details]
A patch back ported from gcc 3.1

Comment 4 hjl 2002-03-26 09:47:39 UTC
Created attachment 50424 [details]
A simple testcase in C.

Comment 5 Jakub Jelinek 2002-03-26 11:45:17 UTC
I prefer a safe short patch at this point, so have fixed it differently
(will appear in 2.96-109 RSN).

Comment 6 hjl 2002-03-27 17:57:44 UTC
I am not sure if the patch in 109 is safe. Please take a look at the asm output
above:

        .section        .gnu.linkonce.t._._9ft_ID_Key,"ax",@progbits
         .align 16
 .LPR0:
         movl    (%esp), %ebx
         ret
         .weak   _._9ft_ID_Key
         .type    _._9ft_ID_Key,@function
 _._9ft_ID_Key:

If I read your patch right,  109 will emit:

        .section        .gnu.linkonce.t._._9ft_ID_Key,"ax",@progbits
         .align 16
         .text
 .LPR0:
         movl    (%esp), %ebx
         ret
         .weak   _._9ft_ID_Key
         .type    _._9ft_ID_Key,@function
 _._9ft_ID_Key:

Shouldn't you add

+#ifdef HAVE_GAS_SUBSECTION_ORDERING
+         if (! in_text_section ())
+           fprintf (asm_out_file, "\t.previous\n");
+#endif

after emitting the stub?


Comment 7 Jakub Jelinek 2002-03-27 18:11:38 UTC
Don't think I get it:
+#ifdef HAVE_GAS_SUBSECTION_ORDERING
+         if (! in_text_section ())
+           fprintf (asm_out_file, "\t%s\n", TEXT_SECTION_ASM_OP);
+#endif
          ASM_OUTPUT_LABEL (file, pic_label_name);

          xops[1] = gen_rtx_MEM (SImode, xops[1]);
          output_asm_insn ("mov{l}\t{%1, %0|%0, %1}", xops);
          output_asm_insn ("ret", xops);
-
+#ifdef HAVE_GAS_SUBSECTION_ORDERING
+         if (! in_text_section ())
+           fprintf (asm_out_file, "\t.previous\n");
+#endif

ie. it will emit:
        .section        .gnu.linkonce.t.foo__Fv,"ax",@progbits
        .align 16
        .text
.LPR0:
        movl    (%esp), %ebx
        ret
        .previous
        .weak   foo__Fv
        .type    foo__Fv,@function
foo__Fv:

Comment 8 hjl 2002-03-27 18:16:59 UTC
Yes,  you want foo__Fv in the .gnu.linkonce.t.foo__Fv section. Without
".previous",
won't  foo__Fv wind up in the .text section?

Comment 9 Jakub Jelinek 2002-03-27 18:20:42 UTC
But I do emit .previous

Comment 10 hjl 2002-03-27 18:24:05 UTC
Oops. Somehow, I missed the ".previous" part.

Comment 11 Jakub Jelinek 2002-03-29 09:50:29 UTC
Fixed in gcc-2.96-109 and 2.96-108.1.

Comment 12 Bill Nottingham 2002-07-26 21:47:25 UTC
An errata has been issued which should help the problem described in this bug report. 
This report is therefore being closed with a resolution of ERRATA. For more information
on the solution and/or where to find the updated files, please follow the link below. You may reopen 
this bug report if the solution does not work for you.

http://rhn.redhat.com/errata/RHBA-2002-055.html



Note You need to log in before you can comment on or make changes to this bug.