Bug 33171 - GCC outputs invalid assembly when using -O2
Summary: GCC outputs invalid assembly when using -O2
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: inline-asm (show other bugs)
Version: 4.2.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-08-24 05:01 UTC by ianw
Modified: 2007-08-29 00:53 UTC (History)
2 users (show)

See Also:
Host: powerpc64-unknown-linux-gnu
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
-S output with no optimisation (434 bytes, application/octet-stream)
2007-08-24 05:04 UTC, ianw
Details
-S output with -O2 (279 bytes, text/plain)
2007-08-24 05:04 UTC, ianw
Details

Note You need to log in before you can comment on or make changes to this bug.
Description ianw 2007-08-24 05:01:30 UTC
Hi,

The following example, when built with -O2, results in 

~$ .gcc -O2 -o test2 ~/test2.c 
/tmp/cc6SGh7Z.s: Assembler messages:
/tmp/cc6SGh7Z.s:16: Error: syntax error; found `,' but expected `('
/tmp/cc6SGh7Z.s:16: Error: junk at end of line: `,0'

This code is extracted from libatomic-ops (see http://bugs.debian.org/432654) and is causing build failures for some powerpc packages.

4.2.1 and SVN don't fully build on my powerpc64 system (fails comparing objects between stage2->3) but using the partially built stage3 xgcc the same problem happens.

Thanks!

--- testcase ---

static inline unsigned long
load_acquire(volatile unsigned long *addr)
{
  unsigned long result;

  __asm__ __volatile__ (
    "lwz %0,%1\n"
    "cmpw cr7,%0,%0\n"
    "bne- cr7,1f\n"
    "1: isync\n"
    : "=r" (result)
    : "m"(*addr) : "memory", "cc");
  return result;
}

int
main(int argc, char **argv) {
  unsigned long *value, i, res;

  res = load_acquire(value + i);

  return 0;
}
--- end ---
Comment 1 ianw 2007-08-24 05:04:17 UTC
Created attachment 14098 [details]
-S output with no optimisation
Comment 2 ianw 2007-08-24 05:04:46 UTC
Created attachment 14099 [details]
-S output with -O2
Comment 3 Andrew Pinski 2007-08-24 09:02:27 UTC
No, the inline-asm is just wrong, you need to use a different thing for including non indexed load/stores.

The inline-asm function should be written as:
static inline unsigned long
load_acquire(volatile unsigned long *addr)
{
  unsigned long result;

  __asm__ __volatile__ (
    "lwz%X1 %0,%1\n"
    "cmpw cr7,%0,%0\n"
    "bne- cr7,1f\n"
    "1: isync\n"
    : "=r" (result)
    : "m"(*addr) : "memory", "cc");
  return result;
}

Though I will make a mention this is not really atomic at all.  You need to use lwarx/stwcx to be atomic.  Also lwsync should be used instead of isync (IIRC).
Comment 4 Hans Boehm 2007-08-29 00:53:35 UTC
I'll make the %X1 change upstream.  Are there similar issues with some of the other routines?

(See http://bdwgc.cvs.sourceforge.net/bdwgc/bdwgc/libatomic_ops-1.2/src/atomic_ops/sysdeps/gcc/powerpc.h?revision=1.3&view=markup )

Based on Book 2, section 1.4 of the architecture manual, I believe aligned word
access are always atomic on PowerPC.

The general wisdom among the experts I've talked to seems to be that a conditional branch followed by isync is cheaper than an lwsync, and sufficient for an acquire load.
Comment 5 pinskia@gmail.com 2007-08-29 00:56:41 UTC
Subject: Re:  GCC outputs invalid assembly when using -O2

On 29 Aug 2007 00:53:35 -0000, Hans dot Boehm at hp dot com
<gcc-bugzilla@gcc.gnu.org> wrote:
> Based on Book 2, section 1.4 of the architecture manual, I believe aligned word
> access are always atomic on PowerPC.

They are, even cache-inheited memory too.

-- Pinski