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)
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 --------------------------
Responsible-Changed-From-To: unassigned->ebotcazou Responsible-Changed-Why: Working on a fix.
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.