public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "tanzhangxi at gmail dot com" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug c/50065] New: -Os, -O2, -O3 optimization breaks LD/ST ordering on 32-bit SPARC
Date: Fri, 12 Aug 2011 21:49:00 -0000	[thread overview]
Message-ID: <bug-50065-4@http.gcc.gnu.org/bugzilla/> (raw)

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50065

             Bug #: 50065
           Summary: -Os, -O2, -O3 optimization breaks LD/ST ordering on
                    32-bit SPARC
    Classification: Unclassified
           Product: gcc
           Version: 4.6.1
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: c
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: tanzhangxi@gmail.com


Considering the following C code.

static inline int spinlock_trylock(char* lock)
{
    int reg;
    __asm__ __volatile__ ("ldstub [%1],%0" : "=r"(reg) : "r"(lock) : "memory",
"cc");
    return reg;
}

static inline int spinlock_is_locked(char* lock)
{
    int reg;
    __asm__ __volatile__ ("ldub [%1],%0" : "=r"(reg) : "r"(lock) : "memory");
    return reg;
}


static inline void spinlock_lock(char* lock)
{
    while(spinlock_trylock(lock))
      while(spinlock_is_locked(lock));
}

static inline void spinlock_unlock(char* lock)
{
    *(volatile unsigned char*)lock = 0;
}

char remap_lock;
int remap_barrier;

void inc_remap_barrier()
{

  spinlock_lock(&remap_lock);
  remap_barrier++;
  spinlock_unlock(&remap_lock);
}

A simple ++ counter is protected by a spinlock implemented with the ldstub
atomic instruction on SPARC.

If I use -Os/-O2/-O3 to optimize the code, e.g.
sparc-ramp-gcc -c -Os test.c -o test.o

gcc will generate the following code
00000000 <inc_remap_barrier>:
   0:   03 00 00 00     sethi  %hi(0), %g1
   4:   10 80 00 06     b  1c <inc_remap_barrier+0x1c>
   8:   82 10 60 00     mov  %g1, %g1   ! 0 <inc_remap_barrier>
   c:   c4 08 40 00     ldub  [ %g1 ], %g2
  10:   80 a0 a0 00     cmp  %g2, 0
  14:   12 bf ff fe     bne  c <inc_remap_barrier+0xc>
  18:   01 00 00 00     nop 
  1c:   c4 68 40 00     ldstub  [ %g1 ], %g2
  20:   80 a0 a0 00     cmp  %g2, 0
  24:   12 bf ff fa     bne  c <inc_remap_barrier+0xc>
  28:   05 00 00 00     sethi  %hi(0), %g2
  2c:   c0 28 40 00     clrb  [ %g1 ]
  30:   c6 00 a0 00     ld  [ %g2 ], %g3
  34:   86 00 e0 01     inc  %g3
  38:   81 c3 e0 08     retl 
  3c:   c6 20 a0 00     st  %g3, [ %g2 ]


instruction 2C, clrb [%g1] corresponds to inline function 'spinlock_unlock'
    *(volatile unsigned char*)lock = 0;

This happens before the lock protected content 'remap_barrier++', i.e.

  30:   c6 00 a0 00     ld  [ %g2 ], %g3
  34:   86 00 e0 01     inc  %g3
  38:   81 c3 e0 08     retl 
  3c:   c6 20 a0 00     st  %g3, [ %g2 ]     ---> use the branch delay slot

This is wrong and will cause serious lock issues under a multithreading
environment.

However, the same code works fine with -O1 and -O0

This problem happens with couple of cross GCC builds (4.3.2 / 4.6.1) at our
side with various configurations (with glibc or a bare metal setting).
It breaks with the following configurations:

1. 
COLLECT_GCC=sparc-ramp-gcc
COLLECT_LTO_WRAPPER=/home/charming/toolchain/sparc-ramp/libexec/gcc/sparc-ramp-elf/4.6.1/lto-wrapper
Target: sparc-ramp-elf
Configured with: /home/charming/toolchain/.build/src/gcc-4.6.1/configure
--build=i686-build_pc-linux-gnu --host=i686-build_pc-linux-gnu
--target=sparc-ramp-elf --prefix=/home/charming/toolchain/sparc-ramp
--with-local-prefix=/home/charming/toolchain/sparc-ramp/sparc-ramp-elf/sysroot
--disable-multilib --disable-libmudflap
--with-sysroot=/home/charming/toolchain/sparc-ramp/sparc-ramp-elf/sysroot
--with-newlib --enable-threads=no --disable-shared
--with-pkgversion='crosstool-NG 1.12.0' --disable-__cxa_atexit
--with-gmp=/home/charming/toolchain/.build/sparc-ramp-elf/build/static
--with-mpfr=/home/charming/toolchain/.build/sparc-ramp-elf/build/static
--with-mpc=/home/charming/toolchain/.build/sparc-ramp-elf/build/static
--with-ppl=/home/charming/toolchain/.build/sparc-ramp-elf/build/static
--with-cloog=/home/charming/toolchain/.build/sparc-ramp-elf/build/static
--with-libelf=/home/charming/toolchain/.build/sparc-ramp-elf/build/static
--enable-lto
--with-host-libstdcxx='-L/home/charming/toolchain/.build/sparc-ramp-elf/build/static/lib
-lpwl' --enable-target-optspace --disable-libgomp --disable-libmudflap
--disable-nls --enable-languages=c --with-cpu=v8
Thread model: single
gcc version 4.6.1 (crosstool-NG 1.12.0) 

2.
Using built-in specs.
COLLECT_GCC=sparc-ramp-gcc
COLLECT_LTO_WRAPPER=/home/xtan/toolchain/sparc-ramp/libexec/gcc/sparc-ramp-linux-gnu/4.6.1/lto-wrapper
Target: sparc-ramp-linux-gnu
Configured with: /home/xtan/toolchain/.build/src/gcc-4.6.1/configure
--build=x86_64-build_unknown-linux-gnu --host=x86_64-build_unknown-linux-gnu
--target=sparc-ramp-linux-gnu --prefix=/home/xtan/toolchain/sparc-ramp
--with-sysroot=/home/xtan/toolchain/sparc-ramp/sparc-ramp-linux-gnu/sysroot
--enable-languages=c,c++ --disable-multilib
--with-pkgversion=crosstool-NG-1.11.3 --enable-__cxa_atexit
--disable-libmudflap --disable-libgomp --disable-libssp
--with-gmp=/home/xtan/toolchain/.build/sparc-ramp-linux-gnu/build/static
--with-mpfr=/home/xtan/toolchain/.build/sparc-ramp-linux-gnu/build/static
--with-mpc=/home/xtan/toolchain/.build/sparc-ramp-linux-gnu/build/static
--with-ppl=/home/xtan/toolchain/.build/sparc-ramp-linux-gnu/build/static
--with-cloog=/home/xtan/toolchain/.build/sparc-ramp-linux-gnu/build/static
--with-libelf=/home/xtan/toolchain/.build/sparc-ramp-linux-gnu/build/static
--with-host-libstdcxx='-L/home/xtan/toolchain/.build/sparc-ramp-linux-gnu/build/static/lib
-lpwl' --enable-threads=posix --enable-target-optspace
--with-local-prefix=/home/xtan/toolchain/sparc-ramp/sparc-ramp-linux-gnu/sysroot
--disable-nls --enable-symvers=gnu --enable-c99 --enable-long-long
Thread model: posix
gcc version 4.6.1 (crosstool-NG-1.11.3)


             reply	other threads:[~2011-08-12 21:45 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-08-12 21:49 tanzhangxi at gmail dot com [this message]
2011-08-13  4:33 ` [Bug rtl-optimization/50065] " pinskia at gcc dot gnu.org
2011-08-13 10:12 ` ebotcazou at gcc dot gnu.org
2011-08-14  1:30 ` tanzhangxi at gmail dot com
2011-08-14  4:42 ` tanzhangxi at gmail dot com
2011-08-14  9:38 ` mikpe at it dot uu.se
2011-08-14 13:00 ` ebotcazou at gcc dot gnu.org
2011-08-14 13:11 ` ebotcazou at gcc dot gnu.org
2011-08-14 22:43 ` tanzhangxi at gmail dot com
2011-08-15  8:52 ` ebotcazou at gcc dot gnu.org
2011-08-16  7:29 ` mikpe at it dot uu.se

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-50065-4@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).