Bug 8832 - [3.2/3.3 regression] traditional "asm volatile" code is illegally optimized
Summary: [3.2/3.3 regression] traditional "asm volatile" code is illegally optimized
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: inline-asm (show other bugs)
Version: 3.2
: P3 normal
Target Milestone: ---
Assignee: Eric Botcazou
URL:
Keywords: wrong-code
: 9242 (view as bug list)
Depends on:
Blocks:
 
Reported: 2002-12-05 14:46 UTC by Mark Wielaard
Modified: 2003-07-25 17:33 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Wielaard 2002-12-05 14:46:02 UTC
I have the following test program:

void t(int v)
{
        asm volatile ("movaps %xmm0,%xmm1");
        if(v&7)
                asm volatile ("movaps %xmm1,%xmm2");
        asm volatile ("movaps %xmm2,%xmm1");
        if(v&7)
                asm volatile ("movaps %xmm3,%xmm2");
        asm volatile ("movaps %xmm4,%xmm1");
}


With gcc-3.2/3.2.1/3.3 (Invoked with: gcc -O3 -c bug.cpp) produces the following code:

   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   0f 28 c8                movaps %xmm0,%xmm1
   6:   f6 45 08 07             testb  $0x7,0x8(%ebp)
   a:   74 09                   je     15 <_Z2tti+0x15>
   c:   0f 28 d1                movaps %xmm1,%xmm2
   f:   0f 28 ca                movaps %xmm2,%xmm1
  12:   0f 28 d3                movaps %xmm3,%xmm2
  15:   0f 28 cc                movaps %xmm4,%xmm1
  18:   5d                      pop    %ebp
  19:   c3                      ret

This is not what I want because "movaps %xmm1,%xmm2" is not done if v==7. Is this a bug, or am I doing something wrong ?

gcc -v  Options used: gcc -O3 -c bug.cpp
--------------------------------------------------------------------------
Reading specs from /usr/local/test/lib/gcc-lib/i686-pc-linux-gnu/3.3/specs
Configured with: ../gcc-20021202/configure --prefix=/usr/local/test
Thread model: posix
gcc version 3.3 20021202 (experimental)

The code used to work correctly, gcc 2.95.3 (same system and options) produces the code below, which does excactly what I expect it to do:

   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   0f 28 c8                movaps %xmm0,%xmm1
   6:   8b 45 08                mov    0x8(%ebp),%eax
   9:   83 e0 07                and    $0x7,%eax
   c:   74 03                   je     11 <tt__Fi+0x11>
   e:   0f 28 d1                movaps %xmm1,%xmm2
  11:   0f 28 ca                movaps %xmm2,%xmm1
  14:   85 c0                   test   %eax,%eax
  16:   74 03                   je     1b <tt__Fi+0x1b>
  18:   0f 28 d3                movaps %xmm3,%xmm2
  1b:   0f 28 cc                movaps %xmm4,%xmm1
  1e:   c9                      leave
  1f:   c3                      ret

Release:
3.2 and beyond (2.95.3 was still ok)
Comment 1 Christian Ehrhardt 2002-12-06 04:11:08 UTC
State-Changed-From-To: open->analyzed
State-Changed-Why: I can confirm this with 3.3 on sparc, i.e. it isn't arch independant.
    These two pieces of code produce the same assembler output (except for
    label names) which looks like a bug to me. 3.2.1-prerelease is even
    worse: It completly eliminates two of the volatile asm statements.
    Comile with -O3 -S
    Priority high because this is a regression from 2.95.3
    
    ----------------- variant 1 -------------------------
    void f (int v)
    {
    	asm volatile ("blah p0, p1" );
    	if (v&7) {
    		asm volatile ("blub p0, p1" );
    	}
    	asm volatile ("foo p0, p1");
    	if (v&7) {
    		asm volatile ("bar p0, p1" );
    	}
    	asm volatile ("baz p0, p1" );
    }
    ----------------- end       --------------------------
    ----------------- variant 2 -------------------------
    void f (int v)
    {
    	asm volatile ("blah p0, p1" );
    	if (v&7) {
    		asm volatile ("blub p0, p1" );
    		asm volatile ("foo p0, p1");
    		asm volatile ("bar p0, p1" );
    	}
    	asm volatile ("baz p0, p1" );
    }
    ----------------- end       --------------------------
Comment 2 Eric Botcazou 2002-12-11 11:13:50 UTC
Responsible-Changed-From-To: unassigned->ebotcazou
Responsible-Changed-Why: Working on a fix.
Comment 3 Eric Botcazou 2003-01-10 02:59:33 UTC
State-Changed-From-To: analyzed->closed
State-Changed-Why: 2003-01-09  Eric Botcazou  <ebotcazou@libertysurf.fr>
    
    	PR inline-asm/8832
    	* tree.h (expand_asm): New prototype.
    	* stmt.c (expand_asm): Set the MEM_VOLATILE_P flag if instructed
    	to do so.
    	* c-semantics (genrtl_asm_stmt): Pass the RID_VOLATILE qualifier
    	down to expand_asm.
    	* c-typeck.c (simple_asm_stmt): Set the RID_VOLATILE qualifier.
    	* rtlanal.c (volatile_insn_p) [ASM_INPUT]: Test the MEM_VOLATILE_P flag.
    	(volatile_refs_p) [ASM_INPUT]: Likewise.
    	(side_effects_p) [ASM_INPUT]: Likewise.