Bug 61931 - gcc -O2 -fPIC -march=i686 -mcpu=i686 generates wrong code
gcc -O2 -fPIC -march=i686 -mcpu=i686 generates wrong code
Status: CLOSED ERRATA
Product: Red Hat Linux
Classification: Retired
Component: gcc (Show other bugs)
7.3
i386 Linux
medium Severity medium
: ---
: ---
Assigned To: Jakub Jelinek
:
Depends On:
Blocks: 61590
  Show dependency treegraph
 
Reported: 2002-03-25 20:03 EST by hjl
Modified: 2008-05-01 11:38 EDT (History)
0 users

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


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

  None (edit)
Description hjl 2002-03-25 20:03:38 EST
# 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-25 20:04:25 EST
Created attachment 50364 [details]
A testcase in C++
Comment 2 hjl 2002-03-25 20:04:55 EST
BTW, gcc 3.1 is ok.
Comment 3 hjl 2002-03-25 21:48:14 EST
Created attachment 50384 [details]
A patch back ported from gcc 3.1
Comment 4 hjl 2002-03-26 04:47:39 EST
Created attachment 50424 [details]
A simple testcase in C.
Comment 5 Jakub Jelinek 2002-03-26 06:45:17 EST
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 12:57:44 EST
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 13:11:38 EST
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 13:16:59 EST
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 13:20:42 EST
But I do emit .previous
Comment 10 hjl 2002-03-27 13:24:05 EST
Oops. Somehow, I missed the ".previous" part.
Comment 11 Jakub Jelinek 2002-03-29 04:50:29 EST
Fixed in gcc-2.96-109 and 2.96-108.1.
Comment 12 Bill Nottingham 2002-07-26 17:47:25 EDT
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.