[PATCH] D46386: Adding __atomic_fetch_min/max intrinsics to clang
This revision was automatically updated to reflect the committed changes. Closed by commit rL332193: Added atomic_fetch_min, max, umin, umax intrinsics to clang. (authored by delena, committed by ). Changed prior to commit: https://reviews.llvm.org/D46386?vs=146462=146502#toc Repository: rL LLVM https://reviews.llvm.org/D46386 Files: cfe/trunk/docs/LanguageExtensions.rst cfe/trunk/include/clang/Basic/Builtins.def cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/AST/Expr.cpp cfe/trunk/lib/CodeGen/CGAtomic.cpp cfe/trunk/lib/Sema/SemaChecking.cpp cfe/trunk/test/CodeGen/Atomics.c cfe/trunk/test/Sema/atomic-ops.c Index: cfe/trunk/docs/LanguageExtensions.rst === --- cfe/trunk/docs/LanguageExtensions.rst +++ cfe/trunk/docs/LanguageExtensions.rst @@ -1975,6 +1975,32 @@ Support for constant expression evaluation for the above builtins be detected with ``__has_feature(cxx_constexpr_string_builtins)``. +Atomic Min/Max builtins with memory ordering + + +There are two atomic builtins with min/max in-memory comparison and swap. +The syntax and semantics are similar to GCC-compatible __atomic_* builtins. + +* ``__atomic_fetch_min`` +* ``__atomic_fetch_max`` + +The builtins work with signed and unsigned integers and require to specify memory ordering. +The return value is the original value that was stored in memory before comparison. + +Example: + +.. code-block:: c + + unsigned int val = __atomic_fetch_min(unsigned int *pi, unsigned int ui, __ATOMIC_RELAXED); + +The third argument is one of the memory ordering specifiers ``__ATOMIC_RELAXED``, +``__ATOMIC_CONSUME``, ``__ATOMIC_ACQUIRE``, ``__ATOMIC_RELEASE``, +``__ATOMIC_ACQ_REL``, or ``__ATOMIC_SEQ_CST`` following C++11 memory model semantics. + +In terms or aquire-release ordering barriers these two operations are always +considered as operations with *load-store* semantics, even when the original value +is not actually modified after comparison. + .. _langext-__c11_atomic: __c11_atomic builtins @@ -2734,4 +2760,3 @@ The ``#pragma comment(lib, ...)`` directive is supported on all ELF targets. The second parameter is the library name (without the traditional Unix prefix of ``lib``). This allows you to provide an implicit link of dependent libraries. - Index: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td === --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td @@ -7127,6 +7127,8 @@ def err_atomic_op_needs_atomic_int_or_ptr : Error< "address argument to atomic operation must be a pointer to %select{|atomic }0" "integer or pointer (%1 invalid)">; +def err_atomic_op_needs_int32_or_ptr : Error< + "address argument to atomic operation must be a pointer to signed or unsigned 32-bit integer">; def err_atomic_op_bitwise_needs_atomic_int : Error< "address argument to bitwise atomic operation must be a pointer to " "%select{|atomic }0integer (%1 invalid)">; Index: cfe/trunk/include/clang/Basic/Builtins.def === --- cfe/trunk/include/clang/Basic/Builtins.def +++ cfe/trunk/include/clang/Basic/Builtins.def @@ -721,6 +721,10 @@ ATOMIC_BUILTIN(__opencl_atomic_fetch_min, "v.", "t") ATOMIC_BUILTIN(__opencl_atomic_fetch_max, "v.", "t") +// GCC does not support these, they are a Clang extension. +ATOMIC_BUILTIN(__atomic_fetch_min, "iiD*i.", "t") +ATOMIC_BUILTIN(__atomic_fetch_max, "v.", "t") + #undef ATOMIC_BUILTIN // Non-overloaded atomic builtins. Index: cfe/trunk/test/CodeGen/Atomics.c === --- cfe/trunk/test/CodeGen/Atomics.c +++ cfe/trunk/test/CodeGen/Atomics.c @@ -291,3 +291,10 @@ __sync_lock_release (); // CHECK: store atomic {{.*}} release, align 8 __sync_lock_release (); // CHECK: store atomic {{.*}} release, align 8 } + +void test_atomic(void) { + ui = __atomic_fetch_min(, 5, __ATOMIC_RELAXED); // CHECK: atomicrmw umin {{.*}} monotonic + si = __atomic_fetch_min(, 5, __ATOMIC_SEQ_CST); // CHECK: atomicrmw min {{.*}} seq_cst + ui = __atomic_fetch_max(, 5, __ATOMIC_ACQUIRE); // CHECK: atomicrmw umax {{.*}} acquire + si = __atomic_fetch_max(, 5, __ATOMIC_RELEASE); // CHECK: atomicrmw max {{.*}} release +} Index: cfe/trunk/test/Sema/atomic-ops.c === --- cfe/trunk/test/Sema/atomic-ops.c +++ cfe/trunk/test/Sema/atomic-ops.c @@ -173,6 +173,9 @@ __atomic_fetch_sub(P, 3, memory_order_seq_cst); __atomic_fetch_sub(D, 3, memory_order_seq_cst); // expected-error {{must be a pointer to integer or pointer}} __atomic_fetch_sub(s1, 3, memory_order_seq_cst); // expected-error {{must be a pointer to integer or pointer}} + __atomic_fetch_min(D, 3, memory_order_seq_cst); //
[PATCH] D46386: Adding __atomic_fetch_min/max intrinsics to clang
delena added a comment. In https://reviews.llvm.org/D46386#1096833, @rjmccall wrote: > The actual semantic parts of the diff seem to have disappeared from the patch > posted to Phabricator, for what it's worth. It is not disappeared by itself, I removed it. I understood that you don't see any added value in the entire memory model description inside. Thank you. Repository: rC Clang https://reviews.llvm.org/D46386 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46386: Adding __atomic_fetch_min/max intrinsics to clang
delena updated this revision to Diff 146462. delena added a comment. Added a line about *load-store* semantics of these two intrinsics. Removed the common description of memory modeling. Repository: rC Clang https://reviews.llvm.org/D46386 Files: LanguageExtensions.rst Index: LanguageExtensions.rst === --- LanguageExtensions.rst +++ LanguageExtensions.rst @@ -1975,6 +1975,32 @@ Support for constant expression evaluation for the above builtins be detected with ``__has_feature(cxx_constexpr_string_builtins)``. +Atomic Min/Max builtins with memory ordering + + +There are two atomic builtins with min/max in-memory comparison and swap. +The syntax and semantics are similar to GCC-compatible __atomic_* builtins. + +* ``__atomic_fetch_min`` +* ``__atomic_fetch_max`` + +The builtins work with signed and unsigned integers and require to specify memory ordering. +The return value is the original value that was stored in memory before comparison. + +Example: + +.. code-block:: c + + unsigned int val = __atomic_fetch_min(unsigned int *pi, unsigned int ui, __ATOMIC_RELAXED); + +The third argument is one of the memory ordering specifiers ``__ATOMIC_RELAXED``, +``__ATOMIC_CONSUME``, ``__ATOMIC_ACQUIRE``, ``__ATOMIC_RELEASE``, +``__ATOMIC_ACQ_REL``, or ``__ATOMIC_SEQ_CST`` following C++11 memory model semantics. + +In terms or aquire-release ordering barriers these two operations are always +considered as operations with *load-store* semantics, even when the original value +is not actually modified after comparison. + .. _langext-__c11_atomic: __c11_atomic builtins @@ -2734,4 +2760,3 @@ The ``#pragma comment(lib, ...)`` directive is supported on all ELF targets. The second parameter is the library name (without the traditional Unix prefix of ``lib``). This allows you to provide an implicit link of dependent libraries. - Index: LanguageExtensions.rst === --- LanguageExtensions.rst +++ LanguageExtensions.rst @@ -1975,6 +1975,32 @@ Support for constant expression evaluation for the above builtins be detected with ``__has_feature(cxx_constexpr_string_builtins)``. +Atomic Min/Max builtins with memory ordering + + +There are two atomic builtins with min/max in-memory comparison and swap. +The syntax and semantics are similar to GCC-compatible __atomic_* builtins. + +* ``__atomic_fetch_min`` +* ``__atomic_fetch_max`` + +The builtins work with signed and unsigned integers and require to specify memory ordering. +The return value is the original value that was stored in memory before comparison. + +Example: + +.. code-block:: c + + unsigned int val = __atomic_fetch_min(unsigned int *pi, unsigned int ui, __ATOMIC_RELAXED); + +The third argument is one of the memory ordering specifiers ``__ATOMIC_RELAXED``, +``__ATOMIC_CONSUME``, ``__ATOMIC_ACQUIRE``, ``__ATOMIC_RELEASE``, +``__ATOMIC_ACQ_REL``, or ``__ATOMIC_SEQ_CST`` following C++11 memory model semantics. + +In terms or aquire-release ordering barriers these two operations are always +considered as operations with *load-store* semantics, even when the original value +is not actually modified after comparison. + .. _langext-__c11_atomic: __c11_atomic builtins @@ -2734,4 +2760,3 @@ The ``#pragma comment(lib, ...)`` directive is supported on all ELF targets. The second parameter is the library name (without the traditional Unix prefix of ``lib``). This allows you to provide an implicit link of dependent libraries. - ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46386: Adding __atomic_fetch_min/max intrinsics to clang
delena updated this revision to Diff 146080. delena added a comment. Given more clarification about memory model of atomic operations. Repository: rC Clang https://reviews.llvm.org/D46386 Files: docs/LanguageExtensions.rst include/clang/Basic/Builtins.def include/clang/Basic/DiagnosticSemaKinds.td lib/AST/Expr.cpp lib/CodeGen/CGAtomic.cpp lib/Sema/SemaChecking.cpp test/CodeGen/Atomics.c test/Sema/atomic-ops.c Index: test/Sema/atomic-ops.c === --- test/Sema/atomic-ops.c +++ test/Sema/atomic-ops.c @@ -173,6 +173,9 @@ __atomic_fetch_sub(P, 3, memory_order_seq_cst); __atomic_fetch_sub(D, 3, memory_order_seq_cst); // expected-error {{must be a pointer to integer or pointer}} __atomic_fetch_sub(s1, 3, memory_order_seq_cst); // expected-error {{must be a pointer to integer or pointer}} + __atomic_fetch_min(D, 3, memory_order_seq_cst); // expected-error {{must be a pointer to signed or unsigned 32-bit integer}} + __atomic_fetch_max(P, 3, memory_order_seq_cst); // expected-error {{must be a pointer to signed or unsigned 32-bit integer}} + __atomic_fetch_max(p, 3); // expected-error {{too few arguments to function call, expected 3, have 2}} __c11_atomic_fetch_and(i, 1, memory_order_seq_cst); __c11_atomic_fetch_and(p, 1, memory_order_seq_cst); // expected-error {{must be a pointer to atomic integer}} @@ -456,6 +459,20 @@ (void)__atomic_fetch_nand(p, val, memory_order_acq_rel); (void)__atomic_fetch_nand(p, val, memory_order_seq_cst); + (void)__atomic_fetch_min(p, val, memory_order_relaxed); + (void)__atomic_fetch_min(p, val, memory_order_acquire); + (void)__atomic_fetch_min(p, val, memory_order_consume); + (void)__atomic_fetch_min(p, val, memory_order_release); + (void)__atomic_fetch_min(p, val, memory_order_acq_rel); + (void)__atomic_fetch_min(p, val, memory_order_seq_cst); + + (void)__atomic_fetch_max(p, val, memory_order_relaxed); + (void)__atomic_fetch_max(p, val, memory_order_acquire); + (void)__atomic_fetch_max(p, val, memory_order_consume); + (void)__atomic_fetch_max(p, val, memory_order_release); + (void)__atomic_fetch_max(p, val, memory_order_acq_rel); + (void)__atomic_fetch_max(p, val, memory_order_seq_cst); + (void)__atomic_and_fetch(p, val, memory_order_relaxed); (void)__atomic_and_fetch(p, val, memory_order_acquire); (void)__atomic_and_fetch(p, val, memory_order_consume); Index: test/CodeGen/Atomics.c === --- test/CodeGen/Atomics.c +++ test/CodeGen/Atomics.c @@ -291,3 +291,10 @@ __sync_lock_release (); // CHECK: store atomic {{.*}} release, align 8 __sync_lock_release (); // CHECK: store atomic {{.*}} release, align 8 } + +void test_atomic(void) { + ui = __atomic_fetch_min(, 5, __ATOMIC_RELAXED); // CHECK: atomicrmw umin {{.*}} monotonic + si = __atomic_fetch_min(, 5, __ATOMIC_SEQ_CST); // CHECK: atomicrmw min {{.*}} seq_cst + ui = __atomic_fetch_max(, 5, __ATOMIC_ACQUIRE); // CHECK: atomicrmw umax {{.*}} acquire + si = __atomic_fetch_max(, 5, __ATOMIC_RELEASE); // CHECK: atomicrmw max {{.*}} release +} Index: lib/Sema/SemaChecking.cpp === --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -3037,6 +3037,7 @@ Op == AtomicExpr::AO__atomic_exchange_n || Op == AtomicExpr::AO__atomic_compare_exchange_n; bool IsAddSub = false; + bool IsMinMax = false; switch (Op) { case AtomicExpr::AO__c11_atomic_init: @@ -3090,6 +3091,12 @@ Form = Arithmetic; break; + case AtomicExpr::AO__atomic_fetch_min: + case AtomicExpr::AO__atomic_fetch_max: +IsMinMax = true; +Form = Arithmetic; +break; + case AtomicExpr::AO__c11_atomic_exchange: case AtomicExpr::AO__opencl_atomic_exchange: case AtomicExpr::AO__atomic_exchange_n: @@ -3172,12 +3179,21 @@ // For an arithmetic operation, the implied arithmetic must be well-formed. if (Form == Arithmetic) { // gcc does not enforce these rules for GNU atomics, but we do so for sanity. -if (IsAddSub && !ValType->isIntegerType() && !ValType->isPointerType()) { +if (IsAddSub && !ValType->isIntegerType() +&& !ValType->isPointerType()) { Diag(DRE->getLocStart(), diag::err_atomic_op_needs_atomic_int_or_ptr) << IsC11 << Ptr->getType() << Ptr->getSourceRange(); return ExprError(); } -if (!IsAddSub && !ValType->isIntegerType()) { +if (IsMinMax) { + const BuiltinType *BT = ValType->getAs(); + if (!BT || (BT->getKind() != BuiltinType::Int && + BT->getKind() != BuiltinType::UInt)) { +Diag(DRE->getLocStart(), diag::err_atomic_op_needs_int32_or_ptr); +return ExprError(); + } +} +if (!IsAddSub && !IsMinMax && !ValType->isIntegerType()) { Diag(DRE->getLocStart(),
[PATCH] D46386: Adding __atomic_fetch_min/max intrinsics to clang
delena updated this revision to Diff 145646. delena added a comment. Removed the unsigned version of atomics. Enhanced semantics check. Added more tests. Added documentation. Repository: rC Clang https://reviews.llvm.org/D46386 Files: docs/LanguageExtensions.rst include/clang/Basic/Builtins.def include/clang/Basic/DiagnosticSemaKinds.td lib/AST/Expr.cpp lib/CodeGen/CGAtomic.cpp lib/Sema/SemaChecking.cpp test/CodeGen/Atomics.c test/Sema/atomic-ops.c Index: test/Sema/atomic-ops.c === --- test/Sema/atomic-ops.c +++ test/Sema/atomic-ops.c @@ -173,6 +173,9 @@ __atomic_fetch_sub(P, 3, memory_order_seq_cst); __atomic_fetch_sub(D, 3, memory_order_seq_cst); // expected-error {{must be a pointer to integer or pointer}} __atomic_fetch_sub(s1, 3, memory_order_seq_cst); // expected-error {{must be a pointer to integer or pointer}} + __atomic_fetch_min(D, 3, memory_order_seq_cst); // expected-error {{must be a pointer to signed or unsigned 32-bit integer}} + __atomic_fetch_max(P, 3, memory_order_seq_cst); // expected-error {{must be a pointer to signed or unsigned 32-bit integer}} + __atomic_fetch_max(p, 3); // expected-error {{too few arguments to function call, expected 3, have 2}} __c11_atomic_fetch_and(i, 1, memory_order_seq_cst); __c11_atomic_fetch_and(p, 1, memory_order_seq_cst); // expected-error {{must be a pointer to atomic integer}} @@ -456,6 +459,20 @@ (void)__atomic_fetch_nand(p, val, memory_order_acq_rel); (void)__atomic_fetch_nand(p, val, memory_order_seq_cst); + (void)__atomic_fetch_min(p, val, memory_order_relaxed); + (void)__atomic_fetch_min(p, val, memory_order_acquire); + (void)__atomic_fetch_min(p, val, memory_order_consume); + (void)__atomic_fetch_min(p, val, memory_order_release); + (void)__atomic_fetch_min(p, val, memory_order_acq_rel); + (void)__atomic_fetch_min(p, val, memory_order_seq_cst); + + (void)__atomic_fetch_max(p, val, memory_order_relaxed); + (void)__atomic_fetch_max(p, val, memory_order_acquire); + (void)__atomic_fetch_max(p, val, memory_order_consume); + (void)__atomic_fetch_max(p, val, memory_order_release); + (void)__atomic_fetch_max(p, val, memory_order_acq_rel); + (void)__atomic_fetch_max(p, val, memory_order_seq_cst); + (void)__atomic_and_fetch(p, val, memory_order_relaxed); (void)__atomic_and_fetch(p, val, memory_order_acquire); (void)__atomic_and_fetch(p, val, memory_order_consume); Index: test/CodeGen/Atomics.c === --- test/CodeGen/Atomics.c +++ test/CodeGen/Atomics.c @@ -291,3 +291,10 @@ __sync_lock_release (); // CHECK: store atomic {{.*}} release, align 8 __sync_lock_release (); // CHECK: store atomic {{.*}} release, align 8 } + +void test_atomic(void) { + ui = __atomic_fetch_min(, 5, __ATOMIC_RELAXED); // CHECK: atomicrmw umin {{.*}} monotonic + si = __atomic_fetch_min(, 5, __ATOMIC_SEQ_CST); // CHECK: atomicrmw min {{.*}} seq_cst + ui = __atomic_fetch_max(, 5, __ATOMIC_ACQUIRE); // CHECK: atomicrmw umax {{.*}} acquire + si = __atomic_fetch_max(, 5, __ATOMIC_RELEASE); // CHECK: atomicrmw max {{.*}} release +} Index: lib/Sema/SemaChecking.cpp === --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -3037,6 +3037,7 @@ Op == AtomicExpr::AO__atomic_exchange_n || Op == AtomicExpr::AO__atomic_compare_exchange_n; bool IsAddSub = false; + bool IsMinMax = false; switch (Op) { case AtomicExpr::AO__c11_atomic_init: @@ -3090,6 +3091,12 @@ Form = Arithmetic; break; + case AtomicExpr::AO__atomic_fetch_min: + case AtomicExpr::AO__atomic_fetch_max: +IsMinMax = true; +Form = Arithmetic; +break; + case AtomicExpr::AO__c11_atomic_exchange: case AtomicExpr::AO__opencl_atomic_exchange: case AtomicExpr::AO__atomic_exchange_n: @@ -3172,12 +3179,21 @@ // For an arithmetic operation, the implied arithmetic must be well-formed. if (Form == Arithmetic) { // gcc does not enforce these rules for GNU atomics, but we do so for sanity. -if (IsAddSub && !ValType->isIntegerType() && !ValType->isPointerType()) { +if (IsAddSub && !ValType->isIntegerType() +&& !ValType->isPointerType()) { Diag(DRE->getLocStart(), diag::err_atomic_op_needs_atomic_int_or_ptr) << IsC11 << Ptr->getType() << Ptr->getSourceRange(); return ExprError(); } -if (!IsAddSub && !ValType->isIntegerType()) { +if (IsMinMax) { + const BuiltinType *BT = ValType->getAs(); + if (!BT || (BT->getKind() != BuiltinType::Int && + BT->getKind() != BuiltinType::UInt)) { +Diag(DRE->getLocStart(), diag::err_atomic_op_needs_int32_or_ptr); +return ExprError(); + } +} +if (!IsAddSub && !IsMinMax && !ValType->isIntegerType()) { Diag(DRE->getLocStart(),
[PATCH] D46386: Adding __atomic_fetch_min/max intrinsics to clang
delena added a comment. In https://reviews.llvm.org/D46386#1087533, @Anastasia wrote: > Is this some sort of a vendor extension then? OpenCL 1.2 atomic builtins > don't have ordering parameter. OpenCL 1.2 atomic builtins have relaxed semantics. Always, it is not parameter, it is defined behavior. I want to translate them to atomicrmw instruction and use one of clang intrinsics for this. I can't use _sync_fetch_*, due to the different semantics. The __atomic_* allow to specify semantics, but min/max is missing in this set. Repository: rC Clang https://reviews.llvm.org/D46386 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46386: Adding __atomic_fetch_min/max intrinsics to clang
delena added inline comments. Comment at: lib/Sema/SemaChecking.cpp:3098 + case AtomicExpr::AO__atomic_fetch_umax: +IsMinMax = true; +Form = Arithmetic; jfb wrote: > Should `__sync_fetch_and_min` and others also set `IsMinMax`? __sync_fetch_and_min is not variadic and not overloaded. The types of arguments are defined with the builtin itself in the def file. BUILTIN(__sync_fetch_and_min, "iiD*i", "n"). So it is checked automatically. The other __sync_fetch* functions are overloaded and checked in SemaBuiltinAtomicOverloaded() Repository: rC Clang https://reviews.llvm.org/D46386 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46386: Adding __atomic_fetch_min/max intrinsics to clang
delena created this revision. delena added reviewers: igorb, t.p.northover, ABataev, jfb, rjmccall. Herald added subscribers: cfe-commits, Anastasia. Added __atomic_fetch_min, max, umin, umax intrinsics to clang. These intrinsics work exactly as all other __atomic_fetch_* intrinsics and allow to create *atomicrmw* with ordering. The similar set __sync_fetch_and_min* sets the sequentially-consistent ordering. We use them for OpenCL 1.2, which supports atomic operations with "relaxed" ordering. Repository: rC Clang https://reviews.llvm.org/D46386 Files: include/clang/Basic/Builtins.def lib/AST/Expr.cpp lib/CodeGen/CGAtomic.cpp lib/Sema/SemaChecking.cpp test/Sema/atomic-ops.c Index: test/Sema/atomic-ops.c === --- test/Sema/atomic-ops.c +++ test/Sema/atomic-ops.c @@ -173,6 +173,7 @@ __atomic_fetch_sub(P, 3, memory_order_seq_cst); __atomic_fetch_sub(D, 3, memory_order_seq_cst); // expected-error {{must be a pointer to integer or pointer}} __atomic_fetch_sub(s1, 3, memory_order_seq_cst); // expected-error {{must be a pointer to integer or pointer}} + __atomic_fetch_min(D, 3, memory_order_seq_cst); // expected-error {{must be a pointer to integer or pointer}} __c11_atomic_fetch_and(i, 1, memory_order_seq_cst); __c11_atomic_fetch_and(p, 1, memory_order_seq_cst); // expected-error {{must be a pointer to atomic integer}} @@ -456,6 +457,34 @@ (void)__atomic_fetch_nand(p, val, memory_order_acq_rel); (void)__atomic_fetch_nand(p, val, memory_order_seq_cst); + (void)__atomic_fetch_min(p, val, memory_order_relaxed); + (void)__atomic_fetch_min(p, val, memory_order_acquire); + (void)__atomic_fetch_min(p, val, memory_order_consume); + (void)__atomic_fetch_min(p, val, memory_order_release); + (void)__atomic_fetch_min(p, val, memory_order_acq_rel); + (void)__atomic_fetch_min(p, val, memory_order_seq_cst); + + (void)__atomic_fetch_max(p, val, memory_order_relaxed); + (void)__atomic_fetch_max(p, val, memory_order_acquire); + (void)__atomic_fetch_max(p, val, memory_order_consume); + (void)__atomic_fetch_max(p, val, memory_order_release); + (void)__atomic_fetch_max(p, val, memory_order_acq_rel); + (void)__atomic_fetch_max(p, val, memory_order_seq_cst); + + (void)__atomic_fetch_umin(p, val, memory_order_relaxed); + (void)__atomic_fetch_umin(p, val, memory_order_acquire); + (void)__atomic_fetch_umin(p, val, memory_order_consume); + (void)__atomic_fetch_umin(p, val, memory_order_release); + (void)__atomic_fetch_umin(p, val, memory_order_acq_rel); + (void)__atomic_fetch_umin(p, val, memory_order_seq_cst); + + (void)__atomic_fetch_umax(p, val, memory_order_relaxed); + (void)__atomic_fetch_umax(p, val, memory_order_acquire); + (void)__atomic_fetch_umax(p, val, memory_order_consume); + (void)__atomic_fetch_umax(p, val, memory_order_release); + (void)__atomic_fetch_umax(p, val, memory_order_acq_rel); + (void)__atomic_fetch_umax(p, val, memory_order_seq_cst); + (void)__atomic_and_fetch(p, val, memory_order_relaxed); (void)__atomic_and_fetch(p, val, memory_order_acquire); (void)__atomic_and_fetch(p, val, memory_order_consume); Index: lib/Sema/SemaChecking.cpp === --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -3037,6 +3037,7 @@ Op == AtomicExpr::AO__atomic_exchange_n || Op == AtomicExpr::AO__atomic_compare_exchange_n; bool IsAddSub = false; + bool IsMinMax = false; switch (Op) { case AtomicExpr::AO__c11_atomic_init: @@ -3090,6 +3091,14 @@ Form = Arithmetic; break; + case AtomicExpr::AO__atomic_fetch_min: + case AtomicExpr::AO__atomic_fetch_max: + case AtomicExpr::AO__atomic_fetch_umin: + case AtomicExpr::AO__atomic_fetch_umax: +IsMinMax = true; +Form = Arithmetic; +break; + case AtomicExpr::AO__c11_atomic_exchange: case AtomicExpr::AO__opencl_atomic_exchange: case AtomicExpr::AO__atomic_exchange_n: @@ -3172,12 +3181,13 @@ // For an arithmetic operation, the implied arithmetic must be well-formed. if (Form == Arithmetic) { // gcc does not enforce these rules for GNU atomics, but we do so for sanity. -if (IsAddSub && !ValType->isIntegerType() && !ValType->isPointerType()) { +if ((IsAddSub || IsMinMax) && !ValType->isIntegerType() +&& !ValType->isPointerType()) { Diag(DRE->getLocStart(), diag::err_atomic_op_needs_atomic_int_or_ptr) << IsC11 << Ptr->getType() << Ptr->getSourceRange(); return ExprError(); } -if (!IsAddSub && !ValType->isIntegerType()) { +if (!IsAddSub && !IsMinMax && !ValType->isIntegerType()) { Diag(DRE->getLocStart(), diag::err_atomic_op_bitwise_needs_atomic_int) << IsC11 << Ptr->getType() << Ptr->getSourceRange(); return ExprError(); Index: lib/CodeGen/CGAtomic.cpp === ---
[PATCH] D37449: [X86][AVX512] _mm512_stream_load_si512 should take a void const* argument (PR33977)
delena accepted this revision. delena added a comment. This revision is now accepted and ready to land. LGTM Repository: rL LLVM https://reviews.llvm.org/D37449 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits