Bug#438415: g++-4.1: [regression] "‘asm’ operand requires impossible reload" building WebKit on PPC
Package: g++-4.1
Version: 4.1.2-15
Severity: important
WebKit fails to build on linux PPC with the following error:
../../../JavaScriptCore/wtf/TCSpinLock.h: In function 'void* TCMalloc_SystemAlloc(size_t, size_t)':
../../../JavaScriptCore/wtf/TCSpinLock.h:98: error: 'asm' operand requires impossible reload
You can check the full relevant source code at the following address:
http://git.debian.org/?p=pkg-webkit/upstream.git;a=blob;f=JavaScriptCore/wtf/TCSystemAlloc.cpp;h=98cb5f73fa65b95d5c76ad772f0f18df74fa8dc1;hb=9ef19fbb3a114100a70c594c519a50145c1332a7
http://git.debian.org/?p=pkg-webkit/upstream.git;a=blob;f=JavaScriptCore/wtf/TCSpinLock.h;h=14c68cbee6737359b5d16cbee478584d18db8a84;hb=9ef19fbb3a114100a70c594c519a50145c1332a7
The attached file contains a reduced testcase that still fails to build
(though the code might not make much sense once reduced)
It has been validated to fail with g++-4.1 4.1.1-21 and g++-4.2 4.2.1-4.
With these versions, it has also been validated to correctly build with
-O0.
It builds fine with -O2 with g++-4.0 4.0.3-3.
For WebKit, I can work around the issue by building with the pthread
generic support, so it is not a blocker issue.
Mike
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
static void SlowLock(volatile unsigned int* lockword);
struct SpinLock {
volatile unsigned int private_lockword_;
inline void Init() { private_lockword_ = 0; }
inline void Finalize() { }
inline void Lock() {
int r;
volatile unsigned int *lockword_ptr = &private_lockword_;
__asm__ __volatile__
("1: lwarx %0, 0, %1\n\t"
"stwcx. %2, 0, %1\n\t"
"bne- 1b\n\t"
"isync"
: "=&r" (r), "=r" (lockword_ptr)
: "r" (1), "1" (lockword_ptr)
: "memory");
if (r) SlowLock(&private_lockword_);
}
inline void Unlock() {
__asm__ __volatile__
("isync\n\t"
"eieio\n\t"
"stw %1, %0"
: "=o" (private_lockword_)
: "r" (0)
: "memory");
}
};
static void SlowLock(volatile unsigned int* lockword) {
int r;
int tmp = 1;
__asm__ __volatile__
("1: lwarx %0, 0, %1\n\t"
"stwcx. %2, 0, %1\n\t"
"bne- 1b\n\t"
"isync"
: "=&r" (r), "=r" (lockword)
: "r" (tmp), "1" (lockword)
: "memory");
}
class SpinLockHolder {
private:
SpinLock* lock_;
public:
inline explicit SpinLockHolder(SpinLock* l)
: lock_(l) { l->Lock(); }
inline ~SpinLockHolder() { lock_->Unlock(); }
};
static SpinLock spinlock = { 0 };
void SystemAlloc(void) {
SpinLockHolder lock_holder(&spinlock);
}
Reply to: