Skip to content

Commit 61d065e

Browse files
committed
Let clang atomic builtins fetch add/sub support floating point types
Recently atomicrmw started to support fadd/fsub: https://reviews.llvm.org/D53965 However clang atomic builtins fetch add/sub still does not support emitting atomicrmw fadd/fsub. This patch adds that. Reviewed by: John McCall, Artem Belevich, Matt Arsenault, JF Bastien, James Y Knight, Louis Dionne, Olivier Giroux Differential Revision: https://reviews.llvm.org/D71726
1 parent ddebed8 commit 61d065e

File tree

8 files changed

+199
-48
lines changed

8 files changed

+199
-48
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8188,6 +8188,9 @@ def err_atomic_op_needs_non_const_pointer : Error<
81888188
def err_atomic_op_needs_trivial_copy : Error<
81898189
"address argument to atomic operation must be a pointer to a "
81908190
"trivially-copyable type (%0 invalid)">;
8191+
def err_atomic_op_needs_atomic_int_ptr_or_fp : Error<
8192+
"address argument to atomic operation must be a pointer to %select{|atomic }0"
8193+
"integer, pointer or supported floating point type (%1 invalid)">;
81918194
def err_atomic_op_needs_atomic_int_or_ptr : Error<
81928195
"address argument to atomic operation must be a pointer to %select{|atomic }0"
81938196
"integer or pointer (%1 invalid)">;

clang/lib/CodeGen/CGAtomic.cpp

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -602,21 +602,25 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
602602
break;
603603

604604
case AtomicExpr::AO__atomic_add_fetch:
605-
PostOp = llvm::Instruction::Add;
605+
PostOp = E->getValueType()->isFloatingType() ? llvm::Instruction::FAdd
606+
: llvm::Instruction::Add;
606607
LLVM_FALLTHROUGH;
607608
case AtomicExpr::AO__c11_atomic_fetch_add:
608609
case AtomicExpr::AO__opencl_atomic_fetch_add:
609610
case AtomicExpr::AO__atomic_fetch_add:
610-
Op = llvm::AtomicRMWInst::Add;
611+
Op = E->getValueType()->isFloatingType() ? llvm::AtomicRMWInst::FAdd
612+
: llvm::AtomicRMWInst::Add;
611613
break;
612614

613615
case AtomicExpr::AO__atomic_sub_fetch:
614-
PostOp = llvm::Instruction::Sub;
616+
PostOp = E->getValueType()->isFloatingType() ? llvm::Instruction::FSub
617+
: llvm::Instruction::Sub;
615618
LLVM_FALLTHROUGH;
616619
case AtomicExpr::AO__c11_atomic_fetch_sub:
617620
case AtomicExpr::AO__opencl_atomic_fetch_sub:
618621
case AtomicExpr::AO__atomic_fetch_sub:
619-
Op = llvm::AtomicRMWInst::Sub;
622+
Op = E->getValueType()->isFloatingType() ? llvm::AtomicRMWInst::FSub
623+
: llvm::AtomicRMWInst::Sub;
620624
break;
621625

622626
case AtomicExpr::AO__atomic_min_fetch:
@@ -813,6 +817,8 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
813817
bool Oversized = getContext().toBits(TInfo.Width) > MaxInlineWidthInBits;
814818
bool Misaligned = (Ptr.getAlignment() % TInfo.Width) != 0;
815819
bool UseLibcall = Misaligned | Oversized;
820+
bool ShouldCastToIntPtrTy = true;
821+
816822
CharUnits MaxInlineWidth =
817823
getContext().toCharUnitsFromBits(MaxInlineWidthInBits);
818824

@@ -892,11 +898,14 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
892898
EmitStoreOfScalar(Val1Scalar, MakeAddrLValue(Temp, Val1Ty));
893899
break;
894900
}
895-
LLVM_FALLTHROUGH;
901+
LLVM_FALLTHROUGH;
896902
case AtomicExpr::AO__atomic_fetch_add:
897903
case AtomicExpr::AO__atomic_fetch_sub:
898904
case AtomicExpr::AO__atomic_add_fetch:
899905
case AtomicExpr::AO__atomic_sub_fetch:
906+
ShouldCastToIntPtrTy = !MemTy->isFloatingType();
907+
LLVM_FALLTHROUGH;
908+
900909
case AtomicExpr::AO__c11_atomic_store:
901910
case AtomicExpr::AO__c11_atomic_exchange:
902911
case AtomicExpr::AO__opencl_atomic_store:
@@ -937,15 +946,23 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
937946
LValue AtomicVal = MakeAddrLValue(Ptr, AtomicTy);
938947
AtomicInfo Atomics(*this, AtomicVal);
939948

940-
Ptr = Atomics.emitCastToAtomicIntPointer(Ptr);
941-
if (Val1.isValid()) Val1 = Atomics.convertToAtomicIntPointer(Val1);
942-
if (Val2.isValid()) Val2 = Atomics.convertToAtomicIntPointer(Val2);
943-
if (Dest.isValid())
944-
Dest = Atomics.emitCastToAtomicIntPointer(Dest);
945-
else if (E->isCmpXChg())
949+
if (ShouldCastToIntPtrTy) {
950+
Ptr = Atomics.emitCastToAtomicIntPointer(Ptr);
951+
if (Val1.isValid())
952+
Val1 = Atomics.convertToAtomicIntPointer(Val1);
953+
if (Val2.isValid())
954+
Val2 = Atomics.convertToAtomicIntPointer(Val2);
955+
}
956+
if (Dest.isValid()) {
957+
if (ShouldCastToIntPtrTy)
958+
Dest = Atomics.emitCastToAtomicIntPointer(Dest);
959+
} else if (E->isCmpXChg())
946960
Dest = CreateMemTemp(RValTy, "cmpxchg.bool");
947-
else if (!RValTy->isVoidType())
948-
Dest = Atomics.emitCastToAtomicIntPointer(Atomics.CreateTempAlloca());
961+
else if (!RValTy->isVoidType()) {
962+
Dest = Atomics.CreateTempAlloca();
963+
if (ShouldCastToIntPtrTy)
964+
Dest = Atomics.emitCastToAtomicIntPointer(Dest);
965+
}
949966

950967
// Use a library call. See: http://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary .
951968
if (UseLibcall) {

clang/lib/Sema/SemaChecking.cpp

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4931,7 +4931,8 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
49314931
case AtomicExpr::AO__atomic_add_fetch:
49324932
case AtomicExpr::AO__atomic_sub_fetch:
49334933
IsAddSub = true;
4934-
LLVM_FALLTHROUGH;
4934+
Form = Arithmetic;
4935+
break;
49354936
case AtomicExpr::AO__c11_atomic_fetch_and:
49364937
case AtomicExpr::AO__c11_atomic_fetch_or:
49374938
case AtomicExpr::AO__c11_atomic_fetch_xor:
@@ -4946,6 +4947,8 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
49464947
case AtomicExpr::AO__atomic_or_fetch:
49474948
case AtomicExpr::AO__atomic_xor_fetch:
49484949
case AtomicExpr::AO__atomic_nand_fetch:
4950+
Form = Arithmetic;
4951+
break;
49494952
case AtomicExpr::AO__c11_atomic_fetch_min:
49504953
case AtomicExpr::AO__c11_atomic_fetch_max:
49514954
case AtomicExpr::AO__opencl_atomic_fetch_min:
@@ -5038,10 +5041,24 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
50385041

50395042
// For an arithmetic operation, the implied arithmetic must be well-formed.
50405043
if (Form == Arithmetic) {
5041-
// gcc does not enforce these rules for GNU atomics, but we do so for sanity.
5042-
if (IsAddSub && !ValType->isIntegerType()
5043-
&& !ValType->isPointerType()) {
5044-
Diag(ExprRange.getBegin(), diag::err_atomic_op_needs_atomic_int_or_ptr)
5044+
// gcc does not enforce these rules for GNU atomics, but we do so for
5045+
// sanity.
5046+
auto IsAllowedValueType = [&](QualType ValType) {
5047+
if (ValType->isIntegerType())
5048+
return true;
5049+
if (ValType->isPointerType())
5050+
return true;
5051+
if (!ValType->isFloatingType())
5052+
return false;
5053+
// LLVM Parser does not allow atomicrmw with x86_fp80 type.
5054+
if (ValType->isSpecificBuiltinType(BuiltinType::LongDouble) &&
5055+
&Context.getTargetInfo().getLongDoubleFormat() ==
5056+
&llvm::APFloat::x87DoubleExtended())
5057+
return false;
5058+
return true;
5059+
};
5060+
if (IsAddSub && !IsAllowedValueType(ValType)) {
5061+
Diag(ExprRange.getBegin(), diag::err_atomic_op_needs_atomic_int_ptr_or_fp)
50455062
<< IsC11 << Ptr->getType() << Ptr->getSourceRange();
50465063
return ExprError();
50475064
}
@@ -5168,7 +5185,9 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
51685185
// passed by address. For the rest, GNU uses by-address and C11 uses
51695186
// by-value.
51705187
assert(Form != Load);
5171-
if (Form == Init || (Form == Arithmetic && ValType->isIntegerType()))
5188+
if (Form == Arithmetic && ValType->isPointerType())
5189+
Ty = Context.getPointerDiffType();
5190+
else if (Form == Init || Form == Arithmetic)
51725191
Ty = ValType;
51735192
else if (Form == Copy || Form == Xchg) {
51745193
if (IsPassedByAddress) {
@@ -5177,9 +5196,7 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
51775196
ExprRange.getBegin());
51785197
}
51795198
Ty = ByValType;
5180-
} else if (Form == Arithmetic)
5181-
Ty = Context.getPointerDiffType();
5182-
else {
5199+
} else {
51835200
Expr *ValArg = APIOrderedArgs[i];
51845201
// The value pointer is always dereferenced, a nullptr is undefined.
51855202
CheckNonNullArgument(*this, ValArg, ExprRange.getBegin());

clang/test/CodeGen/fp-atomic-ops.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// RUN: %clang_cc1 %s -emit-llvm -DDOUBLE -O0 -o - -triple=amdgcn-amd-amdhsa \
2+
// RUN: | opt -instnamer -S | FileCheck -check-prefixes=FLOAT,DOUBLE %s
3+
4+
// RUN: %clang_cc1 %s -emit-llvm -DDOUBLE -O0 -o - -triple=aarch64-linux-gnu \
5+
// RUN: | opt -instnamer -S | FileCheck -check-prefixes=FLOAT,DOUBLE %s
6+
7+
// RUN: %clang_cc1 %s -emit-llvm -O0 -o - -triple=armv8-apple-ios7.0 \
8+
// RUN: | opt -instnamer -S | FileCheck -check-prefixes=FLOAT %s
9+
10+
// RUN: %clang_cc1 %s -emit-llvm -DDOUBLE -O0 -o - -triple=hexagon \
11+
// RUN: | opt -instnamer -S | FileCheck -check-prefixes=FLOAT,DOUBLE %s
12+
13+
// RUN: %clang_cc1 %s -emit-llvm -DDOUBLE -O0 -o - -triple=mips64-mti-linux-gnu \
14+
// RUN: | opt -instnamer -S | FileCheck -check-prefixes=FLOAT,DOUBLE %s
15+
16+
// RUN: %clang_cc1 %s -emit-llvm -O0 -o - -triple=i686-linux-gnu \
17+
// RUN: | opt -instnamer -S | FileCheck -check-prefixes=FLOAT %s
18+
19+
// RUN: %clang_cc1 %s -emit-llvm -DDOUBLE -O0 -o - -triple=x86_64-linux-gnu \
20+
// RUN: | opt -instnamer -S | FileCheck -check-prefixes=FLOAT,DOUBLE %s
21+
22+
typedef enum memory_order {
23+
memory_order_relaxed = __ATOMIC_RELAXED,
24+
memory_order_acquire = __ATOMIC_ACQUIRE,
25+
memory_order_release = __ATOMIC_RELEASE,
26+
memory_order_acq_rel = __ATOMIC_ACQ_REL,
27+
memory_order_seq_cst = __ATOMIC_SEQ_CST
28+
} memory_order;
29+
30+
void test(float *f, float ff, double *d, double dd) {
31+
// FLOAT: atomicrmw fadd float* {{.*}} monotonic
32+
__atomic_fetch_add(f, ff, memory_order_relaxed);
33+
34+
// FLOAT: atomicrmw fsub float* {{.*}} monotonic
35+
__atomic_fetch_sub(f, ff, memory_order_relaxed);
36+
37+
#ifdef DOUBLE
38+
// DOUBLE: atomicrmw fadd double* {{.*}} monotonic
39+
__atomic_fetch_add(d, dd, memory_order_relaxed);
40+
41+
// DOUBLE: atomicrmw fsub double* {{.*}} monotonic
42+
__atomic_fetch_sub(d, dd, memory_order_relaxed);
43+
#endif
44+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// RUN: %clang_cc1 %s -emit-llvm -o - -triple=amdgcn-amd-amdhsa \
2+
// RUN: -fcuda-is-device -target-cpu gfx906 -fnative-half-type \
3+
// RUN: -fnative-half-arguments-and-returns | FileCheck %s
4+
5+
// REQUIRES: amdgpu-registered-target
6+
7+
#include "Inputs/cuda.h"
8+
#include <stdatomic.h>
9+
10+
__device__ float ffp1(float *p) {
11+
// CHECK-LABEL: @_Z4ffp1Pf
12+
// CHECK: atomicrmw fadd float* {{.*}} monotonic
13+
return __atomic_fetch_add(p, 1.0f, memory_order_relaxed);
14+
}
15+
16+
__device__ double ffp2(double *p) {
17+
// CHECK-LABEL: @_Z4ffp2Pd
18+
// CHECK: atomicrmw fsub double* {{.*}} monotonic
19+
return __atomic_fetch_sub(p, 1.0, memory_order_relaxed);
20+
}
21+
22+
// long double is the same as double for amdgcn.
23+
__device__ long double ffp3(long double *p) {
24+
// CHECK-LABEL: @_Z4ffp3Pe
25+
// CHECK: atomicrmw fsub double* {{.*}} monotonic
26+
return __atomic_fetch_sub(p, 1.0L, memory_order_relaxed);
27+
}
28+
29+
__device__ double ffp4(double *p, float f) {
30+
// CHECK-LABEL: @_Z4ffp4Pdf
31+
// CHECK: fpext float {{.*}} to double
32+
// CHECK: atomicrmw fsub double* {{.*}} monotonic
33+
return __atomic_fetch_sub(p, f, memory_order_relaxed);
34+
}
35+
36+
__device__ double ffp5(double *p, int i) {
37+
// CHECK-LABEL: @_Z4ffp5Pdi
38+
// CHECK: sitofp i32 {{.*}} to double
39+
// CHECK: atomicrmw fsub double* {{.*}} monotonic
40+
return __atomic_fetch_sub(p, i, memory_order_relaxed);
41+
}

clang/test/CodeGenOpenCL/atomic-ops.cl

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1-
// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -O0 -o - -triple=amdgcn-amd-amdhsa-amdgizcl | opt -instnamer -S | FileCheck %s
1+
// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -O0 -o - -triple=amdgcn-amd-amdhsa \
2+
// RUN: | opt -instnamer -S | FileCheck %s
23

34
// Also test serialization of atomic operations here, to avoid duplicating the test.
4-
// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-pch -O0 -o %t -triple=amdgcn-amd-amdhsa-amdgizcl
5-
// RUN: %clang_cc1 %s -cl-std=CL2.0 -include-pch %t -O0 -triple=amdgcn-amd-amdhsa-amdgizcl -emit-llvm -o - | opt -instnamer -S | FileCheck %s
5+
// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-pch -O0 -o %t -triple=amdgcn-amd-amdhsa
6+
// RUN: %clang_cc1 %s -cl-std=CL2.0 -include-pch %t -O0 -triple=amdgcn-amd-amdhsa \
7+
// RUN: -emit-llvm -o - | opt -instnamer -S | FileCheck %s
68

79
#ifndef ALREADY_INCLUDED
810
#define ALREADY_INCLUDED
911

12+
#pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable
13+
#pragma OPENCL EXTENSION cl_khr_int64_extended_atomics : enable
14+
1015
typedef __INTPTR_TYPE__ intptr_t;
1116
typedef int int8 __attribute__((ext_vector_type(8)));
1217

@@ -185,6 +190,18 @@ float ff3(atomic_float *d) {
185190
return __opencl_atomic_exchange(d, 2, memory_order_seq_cst, memory_scope_work_group);
186191
}
187192

193+
float ff4(global atomic_float *d, float a) {
194+
// CHECK-LABEL: @ff4
195+
// CHECK: atomicrmw fadd float addrspace(1)* {{.*}} syncscope("workgroup-one-as") monotonic
196+
return __opencl_atomic_fetch_add(d, a, memory_order_relaxed, memory_scope_work_group);
197+
}
198+
199+
float ff5(global atomic_double *d, double a) {
200+
// CHECK-LABEL: @ff5
201+
// CHECK: atomicrmw fadd double addrspace(1)* {{.*}} syncscope("workgroup-one-as") monotonic
202+
return __opencl_atomic_fetch_add(d, a, memory_order_relaxed, memory_scope_work_group);
203+
}
204+
188205
// CHECK-LABEL: @atomic_init_foo
189206
void atomic_init_foo()
190207
{

clang/test/Sema/atomic-ops.c

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
// RUN: %clang_cc1 %s -verify -fgnuc-version=4.2.1 -ffreestanding -fsyntax-only -triple=i686-linux-gnu -std=c11
1+
// RUN: %clang_cc1 %s -verify=expected,fp80,noi128 -fgnuc-version=4.2.1 -ffreestanding \
2+
// RUN: -fsyntax-only -triple=i686-linux-gnu -std=c11
3+
// RUN: %clang_cc1 %s -verify=expected,noi128 -fgnuc-version=4.2.1 -ffreestanding \
4+
// RUN: -fsyntax-only -triple=i686-linux-android -std=c11
5+
// RUN: %clang_cc1 %s -verify -fgnuc-version=4.2.1 -ffreestanding \
6+
// RUN: -fsyntax-only -triple=powerpc64-linux-gnu -std=c11
27

38
// Basic parsing/Sema tests for __c11_atomic_*
49

@@ -51,7 +56,7 @@ _Static_assert(atomic_is_lock_free((atomic_char*)0), "");
5156
_Static_assert(atomic_is_lock_free((atomic_short*)0), "");
5257
_Static_assert(atomic_is_lock_free((atomic_int*)0), "");
5358
_Static_assert(atomic_is_lock_free((atomic_long*)0), "");
54-
// expected-error@+1 {{__int128 is not supported on this target}}
59+
// noi128-error@+1 {{__int128 is not supported on this target}}
5560
_Static_assert(atomic_is_lock_free((_Atomic(__int128)*)0), ""); // expected-error {{not an integral constant expression}}
5661
_Static_assert(atomic_is_lock_free(0 + (atomic_char*)0), "");
5762

@@ -99,7 +104,8 @@ _Static_assert(__atomic_always_lock_free(8, &i64), "");
99104
#define _AS2 __attribute__((address_space(2)))
100105

101106
void f(_Atomic(int) *i, const _Atomic(int) *ci,
102-
_Atomic(int*) *p, _Atomic(float) *d,
107+
_Atomic(int*) *p, _Atomic(float) *f, _Atomic(double) *d,
108+
_Atomic(long double) *ld,
103109
int *I, const int *CI,
104110
int **P, float *D, struct S *s1, struct S *s2) {
105111
__c11_atomic_init(I, 5); // expected-error {{pointer to _Atomic}}
@@ -114,7 +120,7 @@ void f(_Atomic(int) *i, const _Atomic(int) *ci,
114120

115121
__c11_atomic_load(i, memory_order_seq_cst);
116122
__c11_atomic_load(p, memory_order_seq_cst);
117-
__c11_atomic_load(d, memory_order_seq_cst);
123+
__c11_atomic_load(f, memory_order_seq_cst);
118124
__c11_atomic_load(ci, memory_order_seq_cst);
119125

120126
int load_n_1 = __atomic_load_n(I, memory_order_relaxed);
@@ -137,7 +143,7 @@ void f(_Atomic(int) *i, const _Atomic(int) *ci,
137143

138144
__c11_atomic_store(i, 1, memory_order_seq_cst);
139145
__c11_atomic_store(p, 1, memory_order_seq_cst); // expected-warning {{incompatible integer to pointer conversion}}
140-
(int)__c11_atomic_store(d, 1, memory_order_seq_cst); // expected-error {{operand of type 'void'}}
146+
(int)__c11_atomic_store(f, 1, memory_order_seq_cst); // expected-error {{operand of type 'void'}}
141147

142148
__atomic_store_n(I, 4, memory_order_release);
143149
__atomic_store_n(I, 4.0, memory_order_release);
@@ -166,20 +172,22 @@ void f(_Atomic(int) *i, const _Atomic(int) *ci,
166172

167173
__c11_atomic_fetch_add(i, 1, memory_order_seq_cst);
168174
__c11_atomic_fetch_add(p, 1, memory_order_seq_cst);
169-
__c11_atomic_fetch_add(d, 1, memory_order_seq_cst); // expected-error {{must be a pointer to atomic integer or pointer}}
175+
__c11_atomic_fetch_add(f, 1.0f, memory_order_seq_cst);
176+
__c11_atomic_fetch_add(d, 1.0, memory_order_seq_cst);
177+
__c11_atomic_fetch_add(ld, 1.0, memory_order_seq_cst); // fp80-error {{must be a pointer to atomic integer, pointer or supported floating point type}}
170178

171-
__atomic_fetch_add(i, 3, memory_order_seq_cst); // expected-error {{pointer to integer or pointer}}
179+
__atomic_fetch_add(i, 3, memory_order_seq_cst); // expected-error {{pointer to integer, pointer or supported floating point type}}
172180
__atomic_fetch_sub(I, 3, memory_order_seq_cst);
173181
__atomic_fetch_sub(P, 3, memory_order_seq_cst);
174-
__atomic_fetch_sub(D, 3, memory_order_seq_cst); // expected-error {{must be a pointer to integer or pointer}}
175-
__atomic_fetch_sub(s1, 3, memory_order_seq_cst); // expected-error {{must be a pointer to integer or pointer}}
182+
__atomic_fetch_sub(D, 3, memory_order_seq_cst);
183+
__atomic_fetch_sub(s1, 3, memory_order_seq_cst); // expected-error {{must be a pointer to integer, pointer or supported floating point type}}
176184
__atomic_fetch_min(D, 3, memory_order_seq_cst); // expected-error {{must be a pointer to integer}}
177185
__atomic_fetch_max(P, 3, memory_order_seq_cst); // expected-error {{must be a pointer to integer}}
178186
__atomic_fetch_max(p, 3); // expected-error {{too few arguments to function call, expected 3, have 2}}
179187

180188
__c11_atomic_fetch_and(i, 1, memory_order_seq_cst);
181189
__c11_atomic_fetch_and(p, 1, memory_order_seq_cst); // expected-error {{must be a pointer to atomic integer}}
182-
__c11_atomic_fetch_and(d, 1, memory_order_seq_cst); // expected-error {{must be a pointer to atomic integer}}
190+
__c11_atomic_fetch_and(f, 1, memory_order_seq_cst); // expected-error {{must be a pointer to atomic integer}}
183191

184192
__atomic_fetch_and(i, 3, memory_order_seq_cst); // expected-error {{pointer to integer}}
185193
__atomic_fetch_or(I, 3, memory_order_seq_cst);
@@ -189,12 +197,12 @@ void f(_Atomic(int) *i, const _Atomic(int) *ci,
189197

190198
_Bool cmpexch_1 = __c11_atomic_compare_exchange_strong(i, I, 1, memory_order_seq_cst, memory_order_seq_cst);
191199
_Bool cmpexch_2 = __c11_atomic_compare_exchange_strong(p, P, (int*)1, memory_order_seq_cst, memory_order_seq_cst);
192-
_Bool cmpexch_3 = __c11_atomic_compare_exchange_strong(d, I, 1, memory_order_seq_cst, memory_order_seq_cst); // expected-warning {{incompatible pointer types}}
200+
_Bool cmpexch_3 = __c11_atomic_compare_exchange_strong(f, I, 1, memory_order_seq_cst, memory_order_seq_cst); // expected-warning {{incompatible pointer types}}
193201
(void)__c11_atomic_compare_exchange_strong(i, CI, 1, memory_order_seq_cst, memory_order_seq_cst); // expected-warning {{passing 'const int *' to parameter of type 'int *' discards qualifiers}}
194202

195203
_Bool cmpexchw_1 = __c11_atomic_compare_exchange_weak(i, I, 1, memory_order_seq_cst, memory_order_seq_cst);
196204
_Bool cmpexchw_2 = __c11_atomic_compare_exchange_weak(p, P, (int*)1, memory_order_seq_cst, memory_order_seq_cst);
197-
_Bool cmpexchw_3 = __c11_atomic_compare_exchange_weak(d, I, 1, memory_order_seq_cst, memory_order_seq_cst); // expected-warning {{incompatible pointer types}}
205+
_Bool cmpexchw_3 = __c11_atomic_compare_exchange_weak(f, I, 1, memory_order_seq_cst, memory_order_seq_cst); // expected-warning {{incompatible pointer types}}
198206
(void)__c11_atomic_compare_exchange_weak(i, CI, 1, memory_order_seq_cst, memory_order_seq_cst); // expected-warning {{passing 'const int *' to parameter of type 'int *' discards qualifiers}}
199207

200208
_Bool cmpexch_4 = __atomic_compare_exchange_n(I, I, 5, 1, memory_order_seq_cst, memory_order_seq_cst);

0 commit comments

Comments
 (0)