Bug 66477 - __asm__ __volatile__ and &&Llabel constructs disappear
__asm__ __volatile__ and &&Llabel constructs disappear
Status: CLOSED NOTABUG
Product: Red Hat Linux
Classification: Retired
Component: gcc (Show other bugs)
7.1
i686 Linux
high Severity high
: ---
: ---
Assigned To: Jakub Jelinek
Brian Brock
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2002-06-10 22:17 EDT by Jens Troeger
Modified: 2005-10-31 17:00 EST (History)
0 users

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2002-06-11 23:30:38 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:


Attachments (Terms of Use)
.c and .s file (991 bytes, application/octet-stream)
2002-06-10 22:19 EDT, Jens Troeger
no flags Details

  None (edit)
Description Jens Troeger 2002-06-10 22:17:54 EDT
From Bugzilla Helper:
User-Agent: Mozilla/4.77 [en] (X11; U; Linux 2.4.9-31custom i686)

Description of problem:
assembly put into __asm__ __volatile__ are gone in both,
.s and .o files. further, address arithmetic using &&Llabel
is therefore wrong when used in conjuction with inline
assembly. also, the code is moved around in a wrong way. see example source

Version-Release number of selected component (if applicable):
gcc-2.96-85

How reproducible:
Always

Steps to Reproduce:
compile the following main function

int main(int argc, char* argv[]) {
 
        int len = &&Lend - &&Lstart;
        return 0;
 
Lstart:
        __asm__ __volatile__ ("nop; nop");
Lend:
        (void)0;
}

with 

  gcc -S -g3 -O0 test.c

and you will see the following asm

main:
        .stabn 68,0,2,.LM1-main
.LM1:
.LBB2:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $4, %esp
        .stabn 68,0,4,.LM2-main
.LM2:
        movl    $.L3, %eax
        subl    $.L4, %eax
        movl    %eax, -4(%ebp)
        .stabn 68,0,5,.LM3-main
.LM3:
        movl    $0, %eax
.L4:
.L3:
        .stabn 68,0,11,.LM4-main
.LM4:
.LBE2:
        leave
        ret

please note .L3 and .L4 at the wrong place with missing NOP instructions


Actual Results:  see the assembly code

Expected Results:  expected is that there are two NOP instructions between
.L3 and .L4 and that those labels are after the RET
instruction!

Additional info:

rpm -q gcc gives gcc-2.96-85. all the related packages
are installed as well.
Comment 1 Jens Troeger 2002-06-10 22:19:10 EDT
Created attachment 60444 [details]
.c and .s file
Comment 2 Jens Troeger 2002-06-10 22:20:49 EDT
the above code works with 2.95.3 rpms installed, as well as it works with gcc
2.95 under SuSE and Solaris
Comment 3 Jakub Jelinek 2002-06-11 05:42:52 EDT
Your expectations are incorrect. The asm statement is unreachable, so the compiler
is free to optimize it away. It doesn't matter if it is volatile or not.
Comment 4 Jens Troeger 2002-06-11 20:28:08 EDT
the code might be unreachable from the control flow point of view, but it
is referenced through the labels, thus it should not be removed. it is not
ok for a compiler to "optimize away" data.
Comment 5 Jens Troeger 2002-06-11 20:29:18 EDT
the code might be unreachable from the control flow point of view, but it
is referenced through the labels, thus it should not be removed. it is not
ok for a compiler to "optimize away" data.
Comment 6 Jens Troeger 2002-06-11 21:06:27 EDT
and if you check out the gcc docs

  http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_4.html#SEC93

it says there:

  "You can prevent an asm instruction from being deleted, moved
  significantly, or combined, by writing the keyword volatile after
  the asm"

cheers....
Comment 7 Jakub Jelinek 2002-06-12 05:27:16 EDT
But you are not using gcc 2.95, are you?
2.96-RH info gcc writes e.g.:
   An `asm' instruction without any operands or clobbers (and "old
style" `asm') will not be deleted or moved significantly, regardless,
unless it is unreachable, the same wasy as if you had written a
`volatile' keyword.
and 3.1 info gcc is even more clear:
   The `volatile' keyword indicates that the instruction has important
side-effects.  GCC will not delete a volatile `asm' if it is reachable.
(The instruction can still be deleted if GCC can prove that
control-flow will never reach the location of the instruction.)  In
addition, GCC will not reschedule instructions across a volatile `asm'
instruction.

Your asm is not reachable, although you take the address of the labels, you never
jump to it (if you e.g. void *f = &&Lstart; goto *f; somewhere in reachable
code the asm will not be optimized away).
Your code is equal to writing if (0) { asm volatile ("nop; nop"); } which is
optimized away too.
Comment 8 Jens Troeger 2002-06-12 19:46:12 EDT
well i dont really agree, but anyway... here is a workaround:

static bool phony = false;
int main(int argc, char* argv[]) {
        if (phony) goto Lstart;

        int len = &&Lend - &&Lstart;
        return 0; 
Lstart:
        __asm__ __volatile__ ("nop; nop");
Lend:
        (void)0;
}

that prevents the code from being dead and, thus, from being deleted.
not very elegant (which workaround is elegant anyway?!) but it seems
to work. 

(i use those constructs quite often, and not only with __asm__ in it; its
to generate code that i can copy around and execute at runtime)

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