https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84041
Tom de Vries <vries at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Keywords| |wrong-code
Status|UNCONFIRMED |NEW
Last reconfirmed| |2018-04-09
CC| |chunglin.tang at gmail dot com
Component|libgomp |target
Ever confirmed|0 |1
--- Comment #4 from Tom de Vries <vries at gcc dot gnu.org> ---
The hang was pinpointed by Chung-Lin to the atomic load in gomp_ptrlock_get in
libgomp/config/nvptx/ptrlock.h:
...
static inline void *gomp_ptrlock_get (gomp_ptrlock_t *ptrlock)
{
uintptr_t v = (uintptr_t) __atomic_load_n (ptrlock, MEMMODEL_ACQUIRE);
if (v > 2)
return (void *) v;
if (v == 0
&& __atomic_compare_exchange_n (ptrlock, &v, 1, false,
MEMMODEL_ACQUIRE, MEMMODEL_ACQUIRE))
return NULL;
while (v == 1)
v = (uintptr_t) __atomic_load_n (ptrlock, MEMMODEL_ACQUIRE);
return (void *) v;
}
...
There's no atomic load insn defined for nvptx, and also no memory barrier insn,
so the atomic load ends up generating a normal load.
The JIT compiler does loop-invariant code motion, and moves the load out of the
loop, which turns the while into an eternal loop.
A conservative fix is to define the memory_barrier insn as membar.sys.