clang-fix-cmpxchg8-detection-on-i386
authorLLVM Packaging Team <pkg-llvm-team@lists.alioth.debian.org>
Sat, 15 Apr 2017 10:03:30 +0000 (10:03 +0000)
committerSylvestre Ledru <sylvestre@debian.org>
Sat, 15 Apr 2017 10:03:30 +0000 (10:03 +0000)
libcxx atomic tests for old i386 fail with wrong Atomic inline width.
cmpxchg8b instruction is required for 8 byte atomics that clang was
assuming.

Too bad _GCC_ATOMIC_LLONG_LOCK_FREE 2 isn't supported even with this change
because llvm doesn't support unaligned atomic compare and exchange operation.
Fallback calls to libatomic.so should handle long long lock free but clang
can't tell program if libatomic is always lock free.

Related bug: https://llvm.org/bugs/show_bug.cgi?id=19355

Gbp-Pq: Name clang-fix-cmpxchg8-detection-on-i386.patch

clang/lib/Basic/Targets.cpp
clang/test/Sema/atomic-ops.c

index 036430c36f3d922888d2bbe89013dbbc9b8bd80e..2b158c59ffa8e068f396459889a6b1eb352a846a 100644 (file)
@@ -2622,7 +2622,10 @@ class X86TargetInfo : public TargetInfo {
     FP_SSE,
     FP_387
   } FPMath = FP_Default;
-
+protected:
+  bool isCmpXChg8Supported() const {
+    return CPU >= CK_i586;
+  }
 public:
   X86TargetInfo(const llvm::Triple &Triple, const TargetOptions &)
       : TargetInfo(Triple) {
@@ -2714,6 +2717,8 @@ public:
     // acceptable.
     // FIXME: This results in terrible diagnostics. Clang just says the CPU is
     // invalid without explaining *why*.
+    if (!isCmpXChg8Supported())
+        MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
     switch (CPU) {
     case CK_Generic:
       // No processor selected!
@@ -3743,7 +3748,7 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
   }
-  if (CPU >= CK_i586)
+  if (isCmpXChg8Supported())
     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
 }
 
@@ -4022,8 +4027,6 @@ public:
                              (1 << TargetInfo::LongDouble));
 
     // x86-32 has atomics up to 8 bytes
-    // FIXME: Check that we actually have cmpxchg8b before setting
-    // MaxAtomicInlineWidth. (cmpxchg8b is an i586 instruction.)
     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
   }
   BuiltinVaListKind getBuiltinVaListKind() const override {
index 05836214247c8a923a42885d50bbfc25241961d3..d4599649c69ac9c54bee081ccea0fb6e887ffa33 100644 (file)
@@ -14,7 +14,7 @@ _Static_assert(__GCC_ATOMIC_WCHAR_T_LOCK_FREE == 2, "");
 _Static_assert(__GCC_ATOMIC_SHORT_LOCK_FREE == 2, "");
 _Static_assert(__GCC_ATOMIC_INT_LOCK_FREE == 2, "");
 _Static_assert(__GCC_ATOMIC_LONG_LOCK_FREE == 2, "");
-#ifdef __i386__
+#if defined(__i386__)
 _Static_assert(__GCC_ATOMIC_LLONG_LOCK_FREE == 1, "");
 #else
 _Static_assert(__GCC_ATOMIC_LLONG_LOCK_FREE == 2, "");