[llvm] [LoongArch] Improve codegen for atomic ops (PR #67391)

via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 8 23:20:26 PDT 2023


heiher wrote:

A test case for cmpxchg acquire. Without this patch, the unexpected behavior can be reproduced on the 3A6000. This can also be reproduced with the GCC compiler.

Source: https://gist.github.com/heiher/76a42a083df9359c01be0c573ab17734

```c
/*
 ============================================================================
 Name        : cmpxchg-acquire-test.c
 Author      : WANG Rui <wangrui at loongson.cn>
 Copyright   : Copyright (c) 2023 Loongson
 Description : A test case for cmpxchg acquire (3A6000)
 ============================================================================
 */

#include <stdio.h>
#include <stdbool.h>
#include <stdatomic.h>
#include <pthread.h>

static unsigned int tags[32];
static unsigned int vals[32];

static void *
writer_entry (void *data)
{
    atomic_ulong *pt = (atomic_ulong *)tags;
    atomic_ulong *pv = (atomic_ulong *)vals;
    unsigned int n = 1;

    for (; n;) {
        atomic_store_explicit (&pv[n & 31], n, memory_order_release);
        atomic_store_explicit (&pt[n & 31], n, memory_order_release);
        n++;
    }

    return NULL;
}

static void *
reader_entry (void *data)
{
    atomic_uint *pt = (atomic_uint *)tags;
    atomic_uint *pv = (atomic_uint *)vals;
    int i;

    for (;;) {
        for (i = 0; i < 32; i++) {
            unsigned int tag = 0;
            bool res;

            res = atomic_compare_exchange_weak_explicit (
                &pt[i], &tag, 0, memory_order_acquire, memory_order_acquire);
            if (!res) {
                unsigned int val;

                val = atomic_load_explicit (&pv[i], memory_order_relaxed);
                if (val < tag)
                    printf ("UNEXPECTED: val(%u) < tag(%u)\n", val, tag);
            }
        }
    }

    return NULL;
}

int
main (int argc, char *argv[])
{
    pthread_t writer;
    pthread_t reader;
    int res;

    res = pthread_create (&writer, NULL, writer_entry, NULL);
    if (res < 0)
        return -1;

    res = pthread_create (&reader, NULL, reader_entry, NULL);
    if (res < 0)
        return -1;

    res = pthread_join (writer, NULL);
    if (res < 0)
        return -1;

    printf ("PASSED\n");

    return 0;
}
```

https://github.com/llvm/llvm-project/pull/67391


More information about the llvm-commits mailing list