[llvm-bugs] [Bug 25611] New: Infinite loop in atomic function when built with -O0 on AArch64

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Nov 23 07:16:29 PST 2015


https://llvm.org/bugs/show_bug.cgi?id=25611

            Bug ID: 25611
           Summary: Infinite loop in atomic function when built with -O0
                    on AArch64
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: FreeBSD
            Status: NEW
          Severity: normal
          Priority: P
         Component: Backend: AArch64
          Assignee: unassignedbugs at nondot.org
          Reporter: andrew at fubar.geek.nz
                CC: llvm-bugs at lists.llvm.org
    Classification: Unclassified

When building the following with -O0 it generates code that may, on some
hardware, enter an infinite loop. This is because it is implementation defined
if any store will leave the local-monitor in exclusive mode or not.

int
test(int *ptr, int old_value, int new_value)
{
        return __sync_val_compare_and_swap(ptr, old_value, new_value);
}

When building with -O0 on clang trunk I get the following asm. This is broken
on ThunderX as the local monitor will leave exclusive-mode when it executes the
store at address 40 below.

0000000000000000 <test>:
   0:   d100c3ff        sub     sp, sp, #0x30
   4:   f90017e0        str     x0, [sp,#40]
   8:   b90027e1        str     w1, [sp,#36]
   c:   b90023e2        str     w2, [sp,#32]
  10:   f94017e0        ldr     x0, [sp,#40]
  14:   b94027e1        ldr     w1, [sp,#36]
  18:   b94023e2        ldr     w2, [sp,#32]
  1c:   f9000fe0        str     x0, [sp,#24]
  20:   b90017e1        str     w1, [sp,#20]
  24:   b90013e2        str     w2, [sp,#16]
  28:   f9400fe8        ldr     x8, [sp,#24]
  2c:   885ffd09        ldaxr   w9, [x8]             // Load-exclusive
  30:   2a0903e0        mov     w0, w9
  34:   2a0003e9        mov     w9, w0
  38:   b94017ea        ldr     w10, [sp,#20]
  3c:   6b0a013f        cmp     w9, w10
  40:   b9000fe9        str     w9, [sp,#12]         // Unrelated store
  44:   54000101        b.ne    64 <test+0x64>
  48:   b94013e8        ldr     w8, [sp,#16]
  4c:   2a0803e9        mov     w9, w8
  50:   2a0903e8        mov     w8, w9
  54:   f9400fe9        ldr     x9, [sp,#24]
  58:   880afd28        stlxr   w10, w8, [x9]        // Store-exclusive
  5c:   35fffe6a        cbnz    w10, 28 <test+0x28>
  60:   14000003        b       6c <test+0x6c>
  64:   d5033f5f        clrex
  68:   14000001        b       6c <test+0x6c>
  6c:   b9400fe0        ldr     w0, [sp,#12]
  70:   9100c3ff        add     sp, sp, #0x30
  74:   d65f03c0        ret

The following example will print a different value based on if WITH_STORE is
defined or not.

#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>

int
main(int argc, char *argv[])
{
        uint32_t tmp, a, val, *pa;
        uint32_t b, *pb;
        int res;

        a = 1;
        val = 1;
        pa = &a;
        pb = malloc(sizeof(int));;
        __asm __volatile(
            "1: ldxr    %w0, [%2]      \n"
            "   add     %w0, %w0, %w3  \n"
#if WITH_STORE
            "   str     %w0, [%4]      \n"
#endif
            "   stxr    %w1, %w0, [%2] \n"
            : "=&r"(tmp), "=&r"(res) : "r" (pa), "r" (val), "r" (pb)
            : "cc", "memory"
        );
        printf("res = %x\n", res);
        printf("a = %u\n", a);

        return (0);
}

# clang atomic_test.c -DWITH_STORE
# ./a.out
res = 1
a = 1
# clang atomic_test.c
# ./a.out
res = 0
a = 2

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20151123/6c334ee2/attachment.html>


More information about the llvm-bugs mailing list