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.
Created attachment 60444 [details] .c and .s file
the above code works with 2.95.3 rpms installed, as well as it works with gcc 2.95 under SuSE and Solaris
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.
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.
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....
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.
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)