bharathi seshadri via llvm-dev
2017-Jun-16 14:58 UTC
[llvm-dev] Bug in __sync_bool_compare_and_swap at O0
Debugging a runtime failure with our ARM 32-bit application (at O0), we narrowed it down to a bug in the return values for __sync_bool_compare_and_swap. While it works fine at O1 and above, we sometimes need O0 version to have a better debugging experience. Here is a test case: cat test.c #include <stdio.h> typedef unsigned long long uint64_t; uint64_t x = 10; uint64_t y = 20; uint64_t z = 20; int main() { printf("\nx = %llu y= %llu z=%llu ",x, y, z); int a = __sync_bool_compare_and_swap(&y, z, x); printf("\nx = %llu y= %llu z=%llu result = %d",x, y, z,a); return 0; } The compilation flags used are: --target=armeb-linux-gnueabi -march=armv8-a+crc -mfloat-abi=hard -mfpu=vfp With O0, the expected (y=x) assignment is not done. x = 10 y= 20 z=20 x = 10 y= 20 z=20 result = 0 With O1, it works fine as expected. x = 10 y= 20 z=20 x = 10 y= 10 z=20 result = 1 Both clang4 and trunk have this issue. clang 3.8 did not have this issue. The problem seems to be in how cmpxchg is handled. %2 = cmpxchg i64* @y, i64 %0, i64 %1 seq_cst seq_cst The cmpxchg is left untouched after the atomic-expand pass, which I believe is intentional. I also see several related commits, but with my limited understanding of the backend, I haven't been successful in localizing the problem. Could some one give me pointers with regards to what might be the likely cause or where to look further ? Thanks, Bharathi
Tim Northover via llvm-dev
2017-Jun-16 16:39 UTC
[llvm-dev] Bug in __sync_bool_compare_and_swap at O0
Hi Bharathi, On 16 June 2017 at 07:58, bharathi seshadri via llvm-dev <llvm-dev at lists.llvm.org> wrote:> Could some one give me pointers with regards > to what might be the likely cause or where to look further ?I strongly suspect it's the code that's expanding CMP_SWAP_64 in ARMExpandPseudoInsts.cpp. It looks like it's not written to take account of a big-endian target. Cheers. Tim.