[PATCH] D72579: Evaluate __{c11_,}atomic_is_lock_free to 0 (avoid libcall) if larger than MaxAtomicPromoteWidth
Fangrui Song via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Sun Jan 12 17:28:00 PST 2020
MaskRay created this revision.
MaskRay added reviewers: adalava, dim, nemanjai, jfb, rsmith.
Herald added subscribers: cfe-commits, steven.zhang, dexonsmith, krytarowski, arichardson, emaste.
Herald added a project: clang.
MaxAtomicPromoteWidth is defined as "the maximum width lock-free atomic
operation which will ever be supported for the given target", so an
oversized __c11_atomic_is_lock_free() or __atomic_is_lock_free() can be
evaluated to 0. This is advantageous in some scenarios (e.g. FreeBSD
powerpc, see D71600 <https://reviews.llvm.org/D71600>) to avoid the dependency on libatomic.
The behavior of __atomic_is_lock_free() will diverge from GCC as GCC
never evaluates it to 0 (`gcc/builtins.c:fold_builtin_atomic_always_lock_free`).
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D72579
Files:
clang/lib/AST/ExprConstant.cpp
clang/test/CodeGen/atomic-ops.c
clang/test/CodeGen/big-atomic-ops.c
clang/test/Sema/atomic-ops.c
Index: clang/test/Sema/atomic-ops.c
===================================================================
--- clang/test/Sema/atomic-ops.c
+++ clang/test/Sema/atomic-ops.c
@@ -36,23 +36,23 @@
_Static_assert(__c11_atomic_is_lock_free(3), ""); // expected-error {{not an integral constant expression}}
_Static_assert(__c11_atomic_is_lock_free(4), "");
_Static_assert(__c11_atomic_is_lock_free(8), "");
-_Static_assert(__c11_atomic_is_lock_free(16), ""); // expected-error {{not an integral constant expression}}
-_Static_assert(__c11_atomic_is_lock_free(17), ""); // expected-error {{not an integral constant expression}}
+_Static_assert(!__c11_atomic_is_lock_free(16), "");
+_Static_assert(!__c11_atomic_is_lock_free(17), "");
_Static_assert(__atomic_is_lock_free(1, 0), "");
_Static_assert(__atomic_is_lock_free(2, 0), "");
_Static_assert(__atomic_is_lock_free(3, 0), ""); // expected-error {{not an integral constant expression}}
_Static_assert(__atomic_is_lock_free(4, 0), "");
_Static_assert(__atomic_is_lock_free(8, 0), "");
-_Static_assert(__atomic_is_lock_free(16, 0), ""); // expected-error {{not an integral constant expression}}
-_Static_assert(__atomic_is_lock_free(17, 0), ""); // expected-error {{not an integral constant expression}}
+_Static_assert(!__atomic_is_lock_free(16, 0), "");
+_Static_assert(!__atomic_is_lock_free(17, 0), "");
_Static_assert(atomic_is_lock_free((atomic_char*)0), "");
_Static_assert(atomic_is_lock_free((atomic_short*)0), "");
_Static_assert(atomic_is_lock_free((atomic_int*)0), "");
_Static_assert(atomic_is_lock_free((atomic_long*)0), "");
// expected-error at +1 {{__int128 is not supported on this target}}
-_Static_assert(atomic_is_lock_free((_Atomic(__int128)*)0), ""); // expected-error {{not an integral constant expression}}
+_Static_assert(!atomic_is_lock_free((_Atomic(__int128)*)0), "");
_Static_assert(atomic_is_lock_free(0 + (atomic_char*)0), "");
char i8;
Index: clang/test/CodeGen/big-atomic-ops.c
===================================================================
--- clang/test/CodeGen/big-atomic-ops.c
+++ clang/test/CodeGen/big-atomic-ops.c
@@ -204,9 +204,6 @@
// CHECK: call i32 @__atomic_is_lock_free(i64 16, i8* {{.*}}@sixteen{{.*}})
__atomic_is_lock_free(16, &sixteen);
- // CHECK: call i32 @__atomic_is_lock_free(i64 17, i8* {{.*}}@seventeen{{.*}})
- __atomic_is_lock_free(17, &seventeen);
-
// CHECK: call i32 @__atomic_is_lock_free(i64 4, {{.*}})
__atomic_is_lock_free(4, incomplete);
@@ -215,6 +212,8 @@
__atomic_is_lock_free(4, cs+1);
// CHECK-NOT: call
+ __atomic_is_lock_free(17, &seventeen);
+ __atomic_is_lock_free(32, 0);
__atomic_always_lock_free(3, 0);
__atomic_always_lock_free(16, 0);
__atomic_always_lock_free(17, 0);
Index: clang/test/CodeGen/atomic-ops.c
===================================================================
--- clang/test/CodeGen/atomic-ops.c
+++ clang/test/CodeGen/atomic-ops.c
@@ -346,11 +346,8 @@
// CHECK: call i32 @__atomic_is_lock_free(i32 3, i8* null)
__c11_atomic_is_lock_free(3);
- // CHECK: call i32 @__atomic_is_lock_free(i32 16, i8* {{.*}}@sixteen{{.*}})
- __atomic_is_lock_free(16, &sixteen);
-
- // CHECK: call i32 @__atomic_is_lock_free(i32 17, i8* {{.*}}@seventeen{{.*}})
- __atomic_is_lock_free(17, &seventeen);
+ // CHECK: call i32 @__atomic_is_lock_free(i32 8, i8* {{.*}}@seventeen{{.*}})
+ __atomic_is_lock_free(8, &seventeen);
// CHECK: call i32 @__atomic_is_lock_free(i32 4, {{.*}})
__atomic_is_lock_free(4, incomplete);
@@ -360,6 +357,8 @@
__atomic_is_lock_free(4, cs+1);
// CHECK-NOT: call
+ __atomic_is_lock_free(9, &sixteen);
+ __atomic_is_lock_free(16, 0);
__atomic_always_lock_free(3, 0);
__atomic_always_lock_free(16, 0);
__atomic_always_lock_free(17, 0);
Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -11152,6 +11152,9 @@
// Check power-of-two.
CharUnits Size = CharUnits::fromQuantity(SizeVal.getZExtValue());
+ if (Size > Info.Ctx.toCharUnitsFromBits(
+ Info.Ctx.getTargetInfo().getMaxAtomicPromoteWidth()))
+ return Success(0, E);
if (Size.isPowerOfTwo()) {
// Check against inlining width.
unsigned InlineWidthBits =
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D72579.237567.patch
Type: text/x-patch
Size: 4334 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200113/5d2d769c/attachment-0001.bin>
More information about the cfe-commits
mailing list