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.

Reply via email to