1 //===--- CGAtomic.cpp - Emit LLVM IR for atomic operations ----------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file contains the code for emitting atomic operations.
11 //===----------------------------------------------------------------------===//
14 #include "CGRecordLayout.h"
15 #include "CodeGenFunction.h"
16 #include "CodeGenModule.h"
17 #include "TargetInfo.h"
18 #include "clang/AST/ASTContext.h"
19 #include "clang/CodeGen/CGFunctionInfo.h"
20 #include "clang/Frontend/FrontendDiagnostic.h"
21 #include "llvm/ADT/DenseMap.h"
22 #include "llvm/IR/DataLayout.h"
23 #include "llvm/IR/Intrinsics.h"
24 #include "llvm/IR/Operator.h"
26 using namespace clang
;
27 using namespace CodeGen
;
34 uint64_t AtomicSizeInBits
;
35 uint64_t ValueSizeInBits
;
36 CharUnits AtomicAlign
;
38 TypeEvaluationKind EvaluationKind
;
43 AtomicInfo(CodeGenFunction
&CGF
, LValue
&lvalue
)
44 : CGF(CGF
), AtomicSizeInBits(0), ValueSizeInBits(0),
45 EvaluationKind(TEK_Scalar
), UseLibcall(true) {
46 assert(!lvalue
.isGlobalReg());
47 ASTContext
&C
= CGF
.getContext();
48 if (lvalue
.isSimple()) {
49 AtomicTy
= lvalue
.getType();
50 if (auto *ATy
= AtomicTy
->getAs
<AtomicType
>())
51 ValueTy
= ATy
->getValueType();
54 EvaluationKind
= CGF
.getEvaluationKind(ValueTy
);
56 uint64_t ValueAlignInBits
;
57 uint64_t AtomicAlignInBits
;
58 TypeInfo ValueTI
= C
.getTypeInfo(ValueTy
);
59 ValueSizeInBits
= ValueTI
.Width
;
60 ValueAlignInBits
= ValueTI
.Align
;
62 TypeInfo AtomicTI
= C
.getTypeInfo(AtomicTy
);
63 AtomicSizeInBits
= AtomicTI
.Width
;
64 AtomicAlignInBits
= AtomicTI
.Align
;
66 assert(ValueSizeInBits
<= AtomicSizeInBits
);
67 assert(ValueAlignInBits
<= AtomicAlignInBits
);
69 AtomicAlign
= C
.toCharUnitsFromBits(AtomicAlignInBits
);
70 ValueAlign
= C
.toCharUnitsFromBits(ValueAlignInBits
);
71 if (lvalue
.getAlignment().isZero())
72 lvalue
.setAlignment(AtomicAlign
);
75 } else if (lvalue
.isBitField()) {
76 ValueTy
= lvalue
.getType();
77 ValueSizeInBits
= C
.getTypeSize(ValueTy
);
78 auto &OrigBFI
= lvalue
.getBitFieldInfo();
79 auto Offset
= OrigBFI
.Offset
% C
.toBits(lvalue
.getAlignment());
80 AtomicSizeInBits
= C
.toBits(
81 C
.toCharUnitsFromBits(Offset
+ OrigBFI
.Size
+ C
.getCharWidth() - 1)
82 .alignTo(lvalue
.getAlignment()));
83 llvm::Value
*BitFieldPtr
= lvalue
.getBitFieldPointer();
85 (C
.toCharUnitsFromBits(OrigBFI
.Offset
) / lvalue
.getAlignment()) *
86 lvalue
.getAlignment();
87 llvm::Value
*StoragePtr
= CGF
.Builder
.CreateConstGEP1_64(
88 CGF
.Int8Ty
, BitFieldPtr
, OffsetInChars
.getQuantity());
89 StoragePtr
= CGF
.Builder
.CreateAddrSpaceCast(
90 StoragePtr
, llvm::PointerType::getUnqual(CGF
.getLLVMContext()),
91 "atomic_bitfield_base");
94 BFI
.StorageSize
= AtomicSizeInBits
;
95 BFI
.StorageOffset
+= OffsetInChars
;
96 llvm::Type
*StorageTy
= CGF
.Builder
.getIntNTy(AtomicSizeInBits
);
97 LVal
= LValue::MakeBitfield(
98 Address(StoragePtr
, StorageTy
, lvalue
.getAlignment()), BFI
,
99 lvalue
.getType(), lvalue
.getBaseInfo(), lvalue
.getTBAAInfo());
100 AtomicTy
= C
.getIntTypeForBitwidth(AtomicSizeInBits
, OrigBFI
.IsSigned
);
101 if (AtomicTy
.isNull()) {
104 C
.toCharUnitsFromBits(AtomicSizeInBits
).getQuantity());
106 C
.getConstantArrayType(C
.CharTy
, Size
, nullptr, ArrayType::Normal
,
107 /*IndexTypeQuals=*/0);
109 AtomicAlign
= ValueAlign
= lvalue
.getAlignment();
110 } else if (lvalue
.isVectorElt()) {
111 ValueTy
= lvalue
.getType()->castAs
<VectorType
>()->getElementType();
112 ValueSizeInBits
= C
.getTypeSize(ValueTy
);
113 AtomicTy
= lvalue
.getType();
114 AtomicSizeInBits
= C
.getTypeSize(AtomicTy
);
115 AtomicAlign
= ValueAlign
= lvalue
.getAlignment();
118 assert(lvalue
.isExtVectorElt());
119 ValueTy
= lvalue
.getType();
120 ValueSizeInBits
= C
.getTypeSize(ValueTy
);
121 AtomicTy
= ValueTy
= CGF
.getContext().getExtVectorType(
122 lvalue
.getType(), cast
<llvm::FixedVectorType
>(
123 lvalue
.getExtVectorAddress().getElementType())
125 AtomicSizeInBits
= C
.getTypeSize(AtomicTy
);
126 AtomicAlign
= ValueAlign
= lvalue
.getAlignment();
129 UseLibcall
= !C
.getTargetInfo().hasBuiltinAtomic(
130 AtomicSizeInBits
, C
.toBits(lvalue
.getAlignment()));
133 QualType
getAtomicType() const { return AtomicTy
; }
134 QualType
getValueType() const { return ValueTy
; }
135 CharUnits
getAtomicAlignment() const { return AtomicAlign
; }
136 uint64_t getAtomicSizeInBits() const { return AtomicSizeInBits
; }
137 uint64_t getValueSizeInBits() const { return ValueSizeInBits
; }
138 TypeEvaluationKind
getEvaluationKind() const { return EvaluationKind
; }
139 bool shouldUseLibcall() const { return UseLibcall
; }
140 const LValue
&getAtomicLValue() const { return LVal
; }
141 llvm::Value
*getAtomicPointer() const {
143 return LVal
.getPointer(CGF
);
144 else if (LVal
.isBitField())
145 return LVal
.getBitFieldPointer();
146 else if (LVal
.isVectorElt())
147 return LVal
.getVectorPointer();
148 assert(LVal
.isExtVectorElt());
149 return LVal
.getExtVectorPointer();
151 Address
getAtomicAddress() const {
154 ElTy
= LVal
.getAddress(CGF
).getElementType();
155 else if (LVal
.isBitField())
156 ElTy
= LVal
.getBitFieldAddress().getElementType();
157 else if (LVal
.isVectorElt())
158 ElTy
= LVal
.getVectorAddress().getElementType();
160 ElTy
= LVal
.getExtVectorAddress().getElementType();
161 return Address(getAtomicPointer(), ElTy
, getAtomicAlignment());
164 Address
getAtomicAddressAsAtomicIntPointer() const {
165 return castToAtomicIntPointer(getAtomicAddress());
168 /// Is the atomic size larger than the underlying value type?
170 /// Note that the absence of padding does not mean that atomic
171 /// objects are completely interchangeable with non-atomic
172 /// objects: we might have promoted the alignment of a type
173 /// without making it bigger.
174 bool hasPadding() const {
175 return (ValueSizeInBits
!= AtomicSizeInBits
);
178 bool emitMemSetZeroIfNecessary() const;
180 llvm::Value
*getAtomicSizeValue() const {
181 CharUnits size
= CGF
.getContext().toCharUnitsFromBits(AtomicSizeInBits
);
182 return CGF
.CGM
.getSize(size
);
185 /// Cast the given pointer to an integer pointer suitable for atomic
186 /// operations if the source.
187 Address
castToAtomicIntPointer(Address Addr
) const;
189 /// If Addr is compatible with the iN that will be used for an atomic
190 /// operation, bitcast it. Otherwise, create a temporary that is suitable
191 /// and copy the value across.
192 Address
convertToAtomicIntPointer(Address Addr
) const;
194 /// Turn an atomic-layout object into an r-value.
195 RValue
convertAtomicTempToRValue(Address addr
, AggValueSlot resultSlot
,
196 SourceLocation loc
, bool AsValue
) const;
198 /// Converts a rvalue to integer value.
199 llvm::Value
*convertRValueToInt(RValue RVal
) const;
201 RValue
ConvertIntToValueOrAtomic(llvm::Value
*IntVal
,
202 AggValueSlot ResultSlot
,
203 SourceLocation Loc
, bool AsValue
) const;
205 /// Copy an atomic r-value into atomic-layout memory.
206 void emitCopyIntoMemory(RValue rvalue
) const;
208 /// Project an l-value down to the value field.
209 LValue
projectValue() const {
210 assert(LVal
.isSimple());
211 Address addr
= getAtomicAddress();
213 addr
= CGF
.Builder
.CreateStructGEP(addr
, 0);
215 return LValue::MakeAddr(addr
, getValueType(), CGF
.getContext(),
216 LVal
.getBaseInfo(), LVal
.getTBAAInfo());
219 /// Emits atomic load.
220 /// \returns Loaded value.
221 RValue
EmitAtomicLoad(AggValueSlot ResultSlot
, SourceLocation Loc
,
222 bool AsValue
, llvm::AtomicOrdering AO
,
225 /// Emits atomic compare-and-exchange sequence.
226 /// \param Expected Expected value.
227 /// \param Desired Desired value.
228 /// \param Success Atomic ordering for success operation.
229 /// \param Failure Atomic ordering for failed operation.
230 /// \param IsWeak true if atomic operation is weak, false otherwise.
231 /// \returns Pair of values: previous value from storage (value type) and
232 /// boolean flag (i1 type) with true if success and false otherwise.
233 std::pair
<RValue
, llvm::Value
*>
234 EmitAtomicCompareExchange(RValue Expected
, RValue Desired
,
235 llvm::AtomicOrdering Success
=
236 llvm::AtomicOrdering::SequentiallyConsistent
,
237 llvm::AtomicOrdering Failure
=
238 llvm::AtomicOrdering::SequentiallyConsistent
,
239 bool IsWeak
= false);
241 /// Emits atomic update.
242 /// \param AO Atomic ordering.
243 /// \param UpdateOp Update operation for the current lvalue.
244 void EmitAtomicUpdate(llvm::AtomicOrdering AO
,
245 const llvm::function_ref
<RValue(RValue
)> &UpdateOp
,
247 /// Emits atomic update.
248 /// \param AO Atomic ordering.
249 void EmitAtomicUpdate(llvm::AtomicOrdering AO
, RValue UpdateRVal
,
252 /// Materialize an atomic r-value in atomic-layout memory.
253 Address
materializeRValue(RValue rvalue
) const;
255 /// Creates temp alloca for intermediate operations on atomic value.
256 Address
CreateTempAlloca() const;
258 bool requiresMemSetZero(llvm::Type
*type
) const;
261 /// Emits atomic load as a libcall.
262 void EmitAtomicLoadLibcall(llvm::Value
*AddForLoaded
,
263 llvm::AtomicOrdering AO
, bool IsVolatile
);
264 /// Emits atomic load as LLVM instruction.
265 llvm::Value
*EmitAtomicLoadOp(llvm::AtomicOrdering AO
, bool IsVolatile
);
266 /// Emits atomic compare-and-exchange op as a libcall.
267 llvm::Value
*EmitAtomicCompareExchangeLibcall(
268 llvm::Value
*ExpectedAddr
, llvm::Value
*DesiredAddr
,
269 llvm::AtomicOrdering Success
=
270 llvm::AtomicOrdering::SequentiallyConsistent
,
271 llvm::AtomicOrdering Failure
=
272 llvm::AtomicOrdering::SequentiallyConsistent
);
273 /// Emits atomic compare-and-exchange op as LLVM instruction.
274 std::pair
<llvm::Value
*, llvm::Value
*> EmitAtomicCompareExchangeOp(
275 llvm::Value
*ExpectedVal
, llvm::Value
*DesiredVal
,
276 llvm::AtomicOrdering Success
=
277 llvm::AtomicOrdering::SequentiallyConsistent
,
278 llvm::AtomicOrdering Failure
=
279 llvm::AtomicOrdering::SequentiallyConsistent
,
280 bool IsWeak
= false);
281 /// Emit atomic update as libcalls.
283 EmitAtomicUpdateLibcall(llvm::AtomicOrdering AO
,
284 const llvm::function_ref
<RValue(RValue
)> &UpdateOp
,
286 /// Emit atomic update as LLVM instructions.
287 void EmitAtomicUpdateOp(llvm::AtomicOrdering AO
,
288 const llvm::function_ref
<RValue(RValue
)> &UpdateOp
,
290 /// Emit atomic update as libcalls.
291 void EmitAtomicUpdateLibcall(llvm::AtomicOrdering AO
, RValue UpdateRVal
,
293 /// Emit atomic update as LLVM instructions.
294 void EmitAtomicUpdateOp(llvm::AtomicOrdering AO
, RValue UpdateRal
,
299 Address
AtomicInfo::CreateTempAlloca() const {
300 Address TempAlloca
= CGF
.CreateMemTemp(
301 (LVal
.isBitField() && ValueSizeInBits
> AtomicSizeInBits
) ? ValueTy
303 getAtomicAlignment(),
305 // Cast to pointer to value type for bitfields.
306 if (LVal
.isBitField())
307 return CGF
.Builder
.CreatePointerBitCastOrAddrSpaceCast(
308 TempAlloca
, getAtomicAddress().getType(),
309 getAtomicAddress().getElementType());
313 static RValue
emitAtomicLibcall(CodeGenFunction
&CGF
,
317 const CGFunctionInfo
&fnInfo
=
318 CGF
.CGM
.getTypes().arrangeBuiltinFunctionCall(resultType
, args
);
319 llvm::FunctionType
*fnTy
= CGF
.CGM
.getTypes().GetFunctionType(fnInfo
);
320 llvm::AttrBuilder
fnAttrB(CGF
.getLLVMContext());
321 fnAttrB
.addAttribute(llvm::Attribute::NoUnwind
);
322 fnAttrB
.addAttribute(llvm::Attribute::WillReturn
);
323 llvm::AttributeList fnAttrs
= llvm::AttributeList::get(
324 CGF
.getLLVMContext(), llvm::AttributeList::FunctionIndex
, fnAttrB
);
326 llvm::FunctionCallee fn
=
327 CGF
.CGM
.CreateRuntimeFunction(fnTy
, fnName
, fnAttrs
);
328 auto callee
= CGCallee::forDirect(fn
);
329 return CGF
.EmitCall(fnInfo
, callee
, ReturnValueSlot(), args
);
332 /// Does a store of the given IR type modify the full expected width?
333 static bool isFullSizeType(CodeGenModule
&CGM
, llvm::Type
*type
,
334 uint64_t expectedSize
) {
335 return (CGM
.getDataLayout().getTypeStoreSize(type
) * 8 == expectedSize
);
338 /// Does the atomic type require memsetting to zero before initialization?
340 /// The IR type is provided as a way of making certain queries faster.
341 bool AtomicInfo::requiresMemSetZero(llvm::Type
*type
) const {
342 // If the atomic type has size padding, we definitely need a memset.
343 if (hasPadding()) return true;
345 // Otherwise, do some simple heuristics to try to avoid it:
346 switch (getEvaluationKind()) {
347 // For scalars and complexes, check whether the store size of the
348 // type uses the full size.
350 return !isFullSizeType(CGF
.CGM
, type
, AtomicSizeInBits
);
352 return !isFullSizeType(CGF
.CGM
, type
->getStructElementType(0),
353 AtomicSizeInBits
/ 2);
355 // Padding in structs has an undefined bit pattern. User beware.
359 llvm_unreachable("bad evaluation kind");
362 bool AtomicInfo::emitMemSetZeroIfNecessary() const {
363 assert(LVal
.isSimple());
364 Address addr
= LVal
.getAddress(CGF
);
365 if (!requiresMemSetZero(addr
.getElementType()))
368 CGF
.Builder
.CreateMemSet(
369 addr
.getPointer(), llvm::ConstantInt::get(CGF
.Int8Ty
, 0),
370 CGF
.getContext().toCharUnitsFromBits(AtomicSizeInBits
).getQuantity(),
371 LVal
.getAlignment().getAsAlign());
375 static void emitAtomicCmpXchg(CodeGenFunction
&CGF
, AtomicExpr
*E
, bool IsWeak
,
376 Address Dest
, Address Ptr
,
377 Address Val1
, Address Val2
,
379 llvm::AtomicOrdering SuccessOrder
,
380 llvm::AtomicOrdering FailureOrder
,
381 llvm::SyncScope::ID Scope
) {
382 // Note that cmpxchg doesn't support weak cmpxchg, at least at the moment.
383 llvm::Value
*Expected
= CGF
.Builder
.CreateLoad(Val1
);
384 llvm::Value
*Desired
= CGF
.Builder
.CreateLoad(Val2
);
386 llvm::AtomicCmpXchgInst
*Pair
= CGF
.Builder
.CreateAtomicCmpXchg(
387 Ptr
.getPointer(), Expected
, Desired
, SuccessOrder
, FailureOrder
,
389 Pair
->setVolatile(E
->isVolatile());
390 Pair
->setWeak(IsWeak
);
392 // Cmp holds the result of the compare-exchange operation: true on success,
394 llvm::Value
*Old
= CGF
.Builder
.CreateExtractValue(Pair
, 0);
395 llvm::Value
*Cmp
= CGF
.Builder
.CreateExtractValue(Pair
, 1);
397 // This basic block is used to hold the store instruction if the operation
399 llvm::BasicBlock
*StoreExpectedBB
=
400 CGF
.createBasicBlock("cmpxchg.store_expected", CGF
.CurFn
);
402 // This basic block is the exit point of the operation, we should end up
403 // here regardless of whether or not the operation succeeded.
404 llvm::BasicBlock
*ContinueBB
=
405 CGF
.createBasicBlock("cmpxchg.continue", CGF
.CurFn
);
407 // Update Expected if Expected isn't equal to Old, otherwise branch to the
409 CGF
.Builder
.CreateCondBr(Cmp
, ContinueBB
, StoreExpectedBB
);
411 CGF
.Builder
.SetInsertPoint(StoreExpectedBB
);
412 // Update the memory at Expected with Old's value.
413 CGF
.Builder
.CreateStore(Old
, Val1
);
414 // Finally, branch to the exit point.
415 CGF
.Builder
.CreateBr(ContinueBB
);
417 CGF
.Builder
.SetInsertPoint(ContinueBB
);
418 // Update the memory at Dest with Cmp's value.
419 CGF
.EmitStoreOfScalar(Cmp
, CGF
.MakeAddrLValue(Dest
, E
->getType()));
422 /// Given an ordering required on success, emit all possible cmpxchg
423 /// instructions to cope with the provided (but possibly only dynamically known)
425 static void emitAtomicCmpXchgFailureSet(CodeGenFunction
&CGF
, AtomicExpr
*E
,
426 bool IsWeak
, Address Dest
, Address Ptr
,
427 Address Val1
, Address Val2
,
428 llvm::Value
*FailureOrderVal
,
430 llvm::AtomicOrdering SuccessOrder
,
431 llvm::SyncScope::ID Scope
) {
432 llvm::AtomicOrdering FailureOrder
;
433 if (llvm::ConstantInt
*FO
= dyn_cast
<llvm::ConstantInt
>(FailureOrderVal
)) {
434 auto FOS
= FO
->getSExtValue();
435 if (!llvm::isValidAtomicOrderingCABI(FOS
))
436 FailureOrder
= llvm::AtomicOrdering::Monotonic
;
438 switch ((llvm::AtomicOrderingCABI
)FOS
) {
439 case llvm::AtomicOrderingCABI::relaxed
:
440 // 31.7.2.18: "The failure argument shall not be memory_order_release
441 // nor memory_order_acq_rel". Fallback to monotonic.
442 case llvm::AtomicOrderingCABI::release
:
443 case llvm::AtomicOrderingCABI::acq_rel
:
444 FailureOrder
= llvm::AtomicOrdering::Monotonic
;
446 case llvm::AtomicOrderingCABI::consume
:
447 case llvm::AtomicOrderingCABI::acquire
:
448 FailureOrder
= llvm::AtomicOrdering::Acquire
;
450 case llvm::AtomicOrderingCABI::seq_cst
:
451 FailureOrder
= llvm::AtomicOrdering::SequentiallyConsistent
;
454 // Prior to c++17, "the failure argument shall be no stronger than the
455 // success argument". This condition has been lifted and the only
456 // precondition is 31.7.2.18. Effectively treat this as a DR and skip
457 // language version checks.
458 emitAtomicCmpXchg(CGF
, E
, IsWeak
, Dest
, Ptr
, Val1
, Val2
, Size
, SuccessOrder
,
459 FailureOrder
, Scope
);
463 // Create all the relevant BB's
464 auto *MonotonicBB
= CGF
.createBasicBlock("monotonic_fail", CGF
.CurFn
);
465 auto *AcquireBB
= CGF
.createBasicBlock("acquire_fail", CGF
.CurFn
);
466 auto *SeqCstBB
= CGF
.createBasicBlock("seqcst_fail", CGF
.CurFn
);
467 auto *ContBB
= CGF
.createBasicBlock("atomic.continue", CGF
.CurFn
);
469 // MonotonicBB is arbitrarily chosen as the default case; in practice, this
470 // doesn't matter unless someone is crazy enough to use something that
471 // doesn't fold to a constant for the ordering.
472 llvm::SwitchInst
*SI
= CGF
.Builder
.CreateSwitch(FailureOrderVal
, MonotonicBB
);
473 // Implemented as acquire, since it's the closest in LLVM.
474 SI
->addCase(CGF
.Builder
.getInt32((int)llvm::AtomicOrderingCABI::consume
),
476 SI
->addCase(CGF
.Builder
.getInt32((int)llvm::AtomicOrderingCABI::acquire
),
478 SI
->addCase(CGF
.Builder
.getInt32((int)llvm::AtomicOrderingCABI::seq_cst
),
481 // Emit all the different atomics
482 CGF
.Builder
.SetInsertPoint(MonotonicBB
);
483 emitAtomicCmpXchg(CGF
, E
, IsWeak
, Dest
, Ptr
, Val1
, Val2
,
484 Size
, SuccessOrder
, llvm::AtomicOrdering::Monotonic
, Scope
);
485 CGF
.Builder
.CreateBr(ContBB
);
487 CGF
.Builder
.SetInsertPoint(AcquireBB
);
488 emitAtomicCmpXchg(CGF
, E
, IsWeak
, Dest
, Ptr
, Val1
, Val2
, Size
, SuccessOrder
,
489 llvm::AtomicOrdering::Acquire
, Scope
);
490 CGF
.Builder
.CreateBr(ContBB
);
492 CGF
.Builder
.SetInsertPoint(SeqCstBB
);
493 emitAtomicCmpXchg(CGF
, E
, IsWeak
, Dest
, Ptr
, Val1
, Val2
, Size
, SuccessOrder
,
494 llvm::AtomicOrdering::SequentiallyConsistent
, Scope
);
495 CGF
.Builder
.CreateBr(ContBB
);
497 CGF
.Builder
.SetInsertPoint(ContBB
);
500 /// Duplicate the atomic min/max operation in conventional IR for the builtin
501 /// variants that return the new rather than the original value.
502 static llvm::Value
*EmitPostAtomicMinMax(CGBuilderTy
&Builder
,
503 AtomicExpr::AtomicOp Op
,
507 llvm::CmpInst::Predicate Pred
;
510 llvm_unreachable("Unexpected min/max operation");
511 case AtomicExpr::AO__atomic_max_fetch
:
512 Pred
= IsSigned
? llvm::CmpInst::ICMP_SGT
: llvm::CmpInst::ICMP_UGT
;
514 case AtomicExpr::AO__atomic_min_fetch
:
515 Pred
= IsSigned
? llvm::CmpInst::ICMP_SLT
: llvm::CmpInst::ICMP_ULT
;
518 llvm::Value
*Cmp
= Builder
.CreateICmp(Pred
, OldVal
, RHS
, "tst");
519 return Builder
.CreateSelect(Cmp
, OldVal
, RHS
, "newval");
522 static void EmitAtomicOp(CodeGenFunction
&CGF
, AtomicExpr
*E
, Address Dest
,
523 Address Ptr
, Address Val1
, Address Val2
,
524 llvm::Value
*IsWeak
, llvm::Value
*FailureOrder
,
525 uint64_t Size
, llvm::AtomicOrdering Order
,
526 llvm::SyncScope::ID Scope
) {
527 llvm::AtomicRMWInst::BinOp Op
= llvm::AtomicRMWInst::Add
;
528 bool PostOpMinMax
= false;
531 switch (E
->getOp()) {
532 case AtomicExpr::AO__c11_atomic_init
:
533 case AtomicExpr::AO__opencl_atomic_init
:
534 llvm_unreachable("Already handled!");
536 case AtomicExpr::AO__c11_atomic_compare_exchange_strong
:
537 case AtomicExpr::AO__hip_atomic_compare_exchange_strong
:
538 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong
:
539 emitAtomicCmpXchgFailureSet(CGF
, E
, false, Dest
, Ptr
, Val1
, Val2
,
540 FailureOrder
, Size
, Order
, Scope
);
542 case AtomicExpr::AO__c11_atomic_compare_exchange_weak
:
543 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak
:
544 case AtomicExpr::AO__hip_atomic_compare_exchange_weak
:
545 emitAtomicCmpXchgFailureSet(CGF
, E
, true, Dest
, Ptr
, Val1
, Val2
,
546 FailureOrder
, Size
, Order
, Scope
);
548 case AtomicExpr::AO__atomic_compare_exchange
:
549 case AtomicExpr::AO__atomic_compare_exchange_n
: {
550 if (llvm::ConstantInt
*IsWeakC
= dyn_cast
<llvm::ConstantInt
>(IsWeak
)) {
551 emitAtomicCmpXchgFailureSet(CGF
, E
, IsWeakC
->getZExtValue(), Dest
, Ptr
,
552 Val1
, Val2
, FailureOrder
, Size
, Order
, Scope
);
554 // Create all the relevant BB's
555 llvm::BasicBlock
*StrongBB
=
556 CGF
.createBasicBlock("cmpxchg.strong", CGF
.CurFn
);
557 llvm::BasicBlock
*WeakBB
= CGF
.createBasicBlock("cmxchg.weak", CGF
.CurFn
);
558 llvm::BasicBlock
*ContBB
=
559 CGF
.createBasicBlock("cmpxchg.continue", CGF
.CurFn
);
561 llvm::SwitchInst
*SI
= CGF
.Builder
.CreateSwitch(IsWeak
, WeakBB
);
562 SI
->addCase(CGF
.Builder
.getInt1(false), StrongBB
);
564 CGF
.Builder
.SetInsertPoint(StrongBB
);
565 emitAtomicCmpXchgFailureSet(CGF
, E
, false, Dest
, Ptr
, Val1
, Val2
,
566 FailureOrder
, Size
, Order
, Scope
);
567 CGF
.Builder
.CreateBr(ContBB
);
569 CGF
.Builder
.SetInsertPoint(WeakBB
);
570 emitAtomicCmpXchgFailureSet(CGF
, E
, true, Dest
, Ptr
, Val1
, Val2
,
571 FailureOrder
, Size
, Order
, Scope
);
572 CGF
.Builder
.CreateBr(ContBB
);
574 CGF
.Builder
.SetInsertPoint(ContBB
);
578 case AtomicExpr::AO__c11_atomic_load
:
579 case AtomicExpr::AO__opencl_atomic_load
:
580 case AtomicExpr::AO__hip_atomic_load
:
581 case AtomicExpr::AO__atomic_load_n
:
582 case AtomicExpr::AO__atomic_load
: {
583 llvm::LoadInst
*Load
= CGF
.Builder
.CreateLoad(Ptr
);
584 Load
->setAtomic(Order
, Scope
);
585 Load
->setVolatile(E
->isVolatile());
586 CGF
.Builder
.CreateStore(Load
, Dest
);
590 case AtomicExpr::AO__c11_atomic_store
:
591 case AtomicExpr::AO__opencl_atomic_store
:
592 case AtomicExpr::AO__hip_atomic_store
:
593 case AtomicExpr::AO__atomic_store
:
594 case AtomicExpr::AO__atomic_store_n
: {
595 llvm::Value
*LoadVal1
= CGF
.Builder
.CreateLoad(Val1
);
596 llvm::StoreInst
*Store
= CGF
.Builder
.CreateStore(LoadVal1
, Ptr
);
597 Store
->setAtomic(Order
, Scope
);
598 Store
->setVolatile(E
->isVolatile());
602 case AtomicExpr::AO__c11_atomic_exchange
:
603 case AtomicExpr::AO__hip_atomic_exchange
:
604 case AtomicExpr::AO__opencl_atomic_exchange
:
605 case AtomicExpr::AO__atomic_exchange_n
:
606 case AtomicExpr::AO__atomic_exchange
:
607 Op
= llvm::AtomicRMWInst::Xchg
;
610 case AtomicExpr::AO__atomic_add_fetch
:
611 PostOp
= E
->getValueType()->isFloatingType() ? llvm::Instruction::FAdd
612 : llvm::Instruction::Add
;
614 case AtomicExpr::AO__c11_atomic_fetch_add
:
615 case AtomicExpr::AO__hip_atomic_fetch_add
:
616 case AtomicExpr::AO__opencl_atomic_fetch_add
:
617 case AtomicExpr::AO__atomic_fetch_add
:
618 Op
= E
->getValueType()->isFloatingType() ? llvm::AtomicRMWInst::FAdd
619 : llvm::AtomicRMWInst::Add
;
622 case AtomicExpr::AO__atomic_sub_fetch
:
623 PostOp
= E
->getValueType()->isFloatingType() ? llvm::Instruction::FSub
624 : llvm::Instruction::Sub
;
626 case AtomicExpr::AO__c11_atomic_fetch_sub
:
627 case AtomicExpr::AO__hip_atomic_fetch_sub
:
628 case AtomicExpr::AO__opencl_atomic_fetch_sub
:
629 case AtomicExpr::AO__atomic_fetch_sub
:
630 Op
= E
->getValueType()->isFloatingType() ? llvm::AtomicRMWInst::FSub
631 : llvm::AtomicRMWInst::Sub
;
634 case AtomicExpr::AO__atomic_min_fetch
:
637 case AtomicExpr::AO__c11_atomic_fetch_min
:
638 case AtomicExpr::AO__hip_atomic_fetch_min
:
639 case AtomicExpr::AO__opencl_atomic_fetch_min
:
640 case AtomicExpr::AO__atomic_fetch_min
:
641 Op
= E
->getValueType()->isFloatingType()
642 ? llvm::AtomicRMWInst::FMin
643 : (E
->getValueType()->isSignedIntegerType()
644 ? llvm::AtomicRMWInst::Min
645 : llvm::AtomicRMWInst::UMin
);
648 case AtomicExpr::AO__atomic_max_fetch
:
651 case AtomicExpr::AO__c11_atomic_fetch_max
:
652 case AtomicExpr::AO__hip_atomic_fetch_max
:
653 case AtomicExpr::AO__opencl_atomic_fetch_max
:
654 case AtomicExpr::AO__atomic_fetch_max
:
655 Op
= E
->getValueType()->isFloatingType()
656 ? llvm::AtomicRMWInst::FMax
657 : (E
->getValueType()->isSignedIntegerType()
658 ? llvm::AtomicRMWInst::Max
659 : llvm::AtomicRMWInst::UMax
);
662 case AtomicExpr::AO__atomic_and_fetch
:
663 PostOp
= llvm::Instruction::And
;
665 case AtomicExpr::AO__c11_atomic_fetch_and
:
666 case AtomicExpr::AO__hip_atomic_fetch_and
:
667 case AtomicExpr::AO__opencl_atomic_fetch_and
:
668 case AtomicExpr::AO__atomic_fetch_and
:
669 Op
= llvm::AtomicRMWInst::And
;
672 case AtomicExpr::AO__atomic_or_fetch
:
673 PostOp
= llvm::Instruction::Or
;
675 case AtomicExpr::AO__c11_atomic_fetch_or
:
676 case AtomicExpr::AO__hip_atomic_fetch_or
:
677 case AtomicExpr::AO__opencl_atomic_fetch_or
:
678 case AtomicExpr::AO__atomic_fetch_or
:
679 Op
= llvm::AtomicRMWInst::Or
;
682 case AtomicExpr::AO__atomic_xor_fetch
:
683 PostOp
= llvm::Instruction::Xor
;
685 case AtomicExpr::AO__c11_atomic_fetch_xor
:
686 case AtomicExpr::AO__hip_atomic_fetch_xor
:
687 case AtomicExpr::AO__opencl_atomic_fetch_xor
:
688 case AtomicExpr::AO__atomic_fetch_xor
:
689 Op
= llvm::AtomicRMWInst::Xor
;
692 case AtomicExpr::AO__atomic_nand_fetch
:
693 PostOp
= llvm::Instruction::And
; // the NOT is special cased below
695 case AtomicExpr::AO__c11_atomic_fetch_nand
:
696 case AtomicExpr::AO__atomic_fetch_nand
:
697 Op
= llvm::AtomicRMWInst::Nand
;
701 llvm::Value
*LoadVal1
= CGF
.Builder
.CreateLoad(Val1
);
702 llvm::AtomicRMWInst
*RMWI
=
703 CGF
.Builder
.CreateAtomicRMW(Op
, Ptr
.getPointer(), LoadVal1
, Order
, Scope
);
704 RMWI
->setVolatile(E
->isVolatile());
706 // For __atomic_*_fetch operations, perform the operation again to
707 // determine the value which was written.
708 llvm::Value
*Result
= RMWI
;
710 Result
= EmitPostAtomicMinMax(CGF
.Builder
, E
->getOp(),
711 E
->getValueType()->isSignedIntegerType(),
714 Result
= CGF
.Builder
.CreateBinOp((llvm::Instruction::BinaryOps
)PostOp
, RMWI
,
716 if (E
->getOp() == AtomicExpr::AO__atomic_nand_fetch
)
717 Result
= CGF
.Builder
.CreateNot(Result
);
718 CGF
.Builder
.CreateStore(Result
, Dest
);
721 // This function emits any expression (scalar, complex, or aggregate)
722 // into a temporary alloca.
724 EmitValToTemp(CodeGenFunction
&CGF
, Expr
*E
) {
725 Address DeclPtr
= CGF
.CreateMemTemp(E
->getType(), ".atomictmp");
726 CGF
.EmitAnyExprToMem(E
, DeclPtr
, E
->getType().getQualifiers(),
731 static void EmitAtomicOp(CodeGenFunction
&CGF
, AtomicExpr
*Expr
, Address Dest
,
732 Address Ptr
, Address Val1
, Address Val2
,
733 llvm::Value
*IsWeak
, llvm::Value
*FailureOrder
,
734 uint64_t Size
, llvm::AtomicOrdering Order
,
735 llvm::Value
*Scope
) {
736 auto ScopeModel
= Expr
->getScopeModel();
738 // LLVM atomic instructions always have synch scope. If clang atomic
739 // expression has no scope operand, use default LLVM synch scope.
741 EmitAtomicOp(CGF
, Expr
, Dest
, Ptr
, Val1
, Val2
, IsWeak
, FailureOrder
, Size
,
742 Order
, CGF
.CGM
.getLLVMContext().getOrInsertSyncScopeID(""));
746 // Handle constant scope.
747 if (auto SC
= dyn_cast
<llvm::ConstantInt
>(Scope
)) {
748 auto SCID
= CGF
.getTargetHooks().getLLVMSyncScopeID(
749 CGF
.CGM
.getLangOpts(), ScopeModel
->map(SC
->getZExtValue()),
750 Order
, CGF
.CGM
.getLLVMContext());
751 EmitAtomicOp(CGF
, Expr
, Dest
, Ptr
, Val1
, Val2
, IsWeak
, FailureOrder
, Size
,
756 // Handle non-constant scope.
757 auto &Builder
= CGF
.Builder
;
758 auto Scopes
= ScopeModel
->getRuntimeValues();
759 llvm::DenseMap
<unsigned, llvm::BasicBlock
*> BB
;
760 for (auto S
: Scopes
)
761 BB
[S
] = CGF
.createBasicBlock(getAsString(ScopeModel
->map(S
)), CGF
.CurFn
);
763 llvm::BasicBlock
*ContBB
=
764 CGF
.createBasicBlock("atomic.scope.continue", CGF
.CurFn
);
766 auto *SC
= Builder
.CreateIntCast(Scope
, Builder
.getInt32Ty(), false);
767 // If unsupported synch scope is encountered at run time, assume a fallback
768 // synch scope value.
769 auto FallBack
= ScopeModel
->getFallBackValue();
770 llvm::SwitchInst
*SI
= Builder
.CreateSwitch(SC
, BB
[FallBack
]);
771 for (auto S
: Scopes
) {
774 SI
->addCase(Builder
.getInt32(S
), B
);
776 Builder
.SetInsertPoint(B
);
777 EmitAtomicOp(CGF
, Expr
, Dest
, Ptr
, Val1
, Val2
, IsWeak
, FailureOrder
, Size
,
779 CGF
.getTargetHooks().getLLVMSyncScopeID(CGF
.CGM
.getLangOpts(),
782 CGF
.getLLVMContext()));
783 Builder
.CreateBr(ContBB
);
786 Builder
.SetInsertPoint(ContBB
);
790 AddDirectArgument(CodeGenFunction
&CGF
, CallArgList
&Args
,
791 bool UseOptimizedLibcall
, llvm::Value
*Val
, QualType ValTy
,
792 SourceLocation Loc
, CharUnits SizeInChars
) {
793 if (UseOptimizedLibcall
) {
794 // Load value and pass it to the function directly.
795 CharUnits Align
= CGF
.getContext().getTypeAlignInChars(ValTy
);
796 int64_t SizeInBits
= CGF
.getContext().toBits(SizeInChars
);
798 CGF
.getContext().getIntTypeForBitwidth(SizeInBits
, /*Signed=*/false);
799 llvm::Type
*ITy
= llvm::IntegerType::get(CGF
.getLLVMContext(), SizeInBits
);
800 Address Ptr
= Address(Val
, ITy
, Align
);
801 Val
= CGF
.EmitLoadOfScalar(Ptr
, false,
802 CGF
.getContext().getPointerType(ValTy
),
804 // Coerce the value into an appropriately sized integer type.
805 Args
.add(RValue::get(Val
), ValTy
);
807 // Non-optimized functions always take a reference.
808 Args
.add(RValue::get(Val
), CGF
.getContext().VoidPtrTy
);
812 RValue
CodeGenFunction::EmitAtomicExpr(AtomicExpr
*E
) {
813 QualType AtomicTy
= E
->getPtr()->getType()->getPointeeType();
814 QualType MemTy
= AtomicTy
;
815 if (const AtomicType
*AT
= AtomicTy
->getAs
<AtomicType
>())
816 MemTy
= AT
->getValueType();
817 llvm::Value
*IsWeak
= nullptr, *OrderFail
= nullptr;
819 Address Val1
= Address::invalid();
820 Address Val2
= Address::invalid();
821 Address Dest
= Address::invalid();
822 Address Ptr
= EmitPointerWithAlignment(E
->getPtr());
824 if (E
->getOp() == AtomicExpr::AO__c11_atomic_init
||
825 E
->getOp() == AtomicExpr::AO__opencl_atomic_init
) {
826 LValue lvalue
= MakeAddrLValue(Ptr
, AtomicTy
);
827 EmitAtomicInit(E
->getVal1(), lvalue
);
828 return RValue::get(nullptr);
831 auto TInfo
= getContext().getTypeInfoInChars(AtomicTy
);
832 uint64_t Size
= TInfo
.Width
.getQuantity();
833 unsigned MaxInlineWidthInBits
= getTarget().getMaxAtomicInlineWidth();
835 bool Oversized
= getContext().toBits(TInfo
.Width
) > MaxInlineWidthInBits
;
836 bool Misaligned
= (Ptr
.getAlignment() % TInfo
.Width
) != 0;
837 bool UseLibcall
= Misaligned
| Oversized
;
838 bool ShouldCastToIntPtrTy
= true;
840 CharUnits MaxInlineWidth
=
841 getContext().toCharUnitsFromBits(MaxInlineWidthInBits
);
843 DiagnosticsEngine
&Diags
= CGM
.getDiags();
846 Diags
.Report(E
->getBeginLoc(), diag::warn_atomic_op_misaligned
)
847 << (int)TInfo
.Width
.getQuantity()
848 << (int)Ptr
.getAlignment().getQuantity();
852 Diags
.Report(E
->getBeginLoc(), diag::warn_atomic_op_oversized
)
853 << (int)TInfo
.Width
.getQuantity() << (int)MaxInlineWidth
.getQuantity();
856 llvm::Value
*Order
= EmitScalarExpr(E
->getOrder());
858 E
->getScopeModel() ? EmitScalarExpr(E
->getScope()) : nullptr;
860 switch (E
->getOp()) {
861 case AtomicExpr::AO__c11_atomic_init
:
862 case AtomicExpr::AO__opencl_atomic_init
:
863 llvm_unreachable("Already handled above with EmitAtomicInit!");
865 case AtomicExpr::AO__c11_atomic_load
:
866 case AtomicExpr::AO__opencl_atomic_load
:
867 case AtomicExpr::AO__hip_atomic_load
:
868 case AtomicExpr::AO__atomic_load_n
:
871 case AtomicExpr::AO__atomic_load
:
872 Dest
= EmitPointerWithAlignment(E
->getVal1());
875 case AtomicExpr::AO__atomic_store
:
876 Val1
= EmitPointerWithAlignment(E
->getVal1());
879 case AtomicExpr::AO__atomic_exchange
:
880 Val1
= EmitPointerWithAlignment(E
->getVal1());
881 Dest
= EmitPointerWithAlignment(E
->getVal2());
884 case AtomicExpr::AO__c11_atomic_compare_exchange_strong
:
885 case AtomicExpr::AO__c11_atomic_compare_exchange_weak
:
886 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong
:
887 case AtomicExpr::AO__hip_atomic_compare_exchange_strong
:
888 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak
:
889 case AtomicExpr::AO__hip_atomic_compare_exchange_weak
:
890 case AtomicExpr::AO__atomic_compare_exchange_n
:
891 case AtomicExpr::AO__atomic_compare_exchange
:
892 Val1
= EmitPointerWithAlignment(E
->getVal1());
893 if (E
->getOp() == AtomicExpr::AO__atomic_compare_exchange
)
894 Val2
= EmitPointerWithAlignment(E
->getVal2());
896 Val2
= EmitValToTemp(*this, E
->getVal2());
897 OrderFail
= EmitScalarExpr(E
->getOrderFail());
898 if (E
->getOp() == AtomicExpr::AO__atomic_compare_exchange_n
||
899 E
->getOp() == AtomicExpr::AO__atomic_compare_exchange
)
900 IsWeak
= EmitScalarExpr(E
->getWeak());
903 case AtomicExpr::AO__c11_atomic_fetch_add
:
904 case AtomicExpr::AO__c11_atomic_fetch_sub
:
905 case AtomicExpr::AO__hip_atomic_fetch_add
:
906 case AtomicExpr::AO__hip_atomic_fetch_sub
:
907 case AtomicExpr::AO__opencl_atomic_fetch_add
:
908 case AtomicExpr::AO__opencl_atomic_fetch_sub
:
909 if (MemTy
->isPointerType()) {
910 // For pointer arithmetic, we're required to do a bit of math:
911 // adding 1 to an int* is not the same as adding 1 to a uintptr_t.
912 // ... but only for the C11 builtins. The GNU builtins expect the
913 // user to multiply by sizeof(T).
914 QualType Val1Ty
= E
->getVal1()->getType();
915 llvm::Value
*Val1Scalar
= EmitScalarExpr(E
->getVal1());
916 CharUnits PointeeIncAmt
=
917 getContext().getTypeSizeInChars(MemTy
->getPointeeType());
918 Val1Scalar
= Builder
.CreateMul(Val1Scalar
, CGM
.getSize(PointeeIncAmt
));
919 auto Temp
= CreateMemTemp(Val1Ty
, ".atomictmp");
921 EmitStoreOfScalar(Val1Scalar
, MakeAddrLValue(Temp
, Val1Ty
));
925 case AtomicExpr::AO__atomic_fetch_add
:
926 case AtomicExpr::AO__atomic_fetch_max
:
927 case AtomicExpr::AO__atomic_fetch_min
:
928 case AtomicExpr::AO__atomic_fetch_sub
:
929 case AtomicExpr::AO__atomic_add_fetch
:
930 case AtomicExpr::AO__atomic_max_fetch
:
931 case AtomicExpr::AO__atomic_min_fetch
:
932 case AtomicExpr::AO__atomic_sub_fetch
:
933 case AtomicExpr::AO__c11_atomic_fetch_max
:
934 case AtomicExpr::AO__c11_atomic_fetch_min
:
935 case AtomicExpr::AO__opencl_atomic_fetch_max
:
936 case AtomicExpr::AO__opencl_atomic_fetch_min
:
937 case AtomicExpr::AO__hip_atomic_fetch_max
:
938 case AtomicExpr::AO__hip_atomic_fetch_min
:
939 ShouldCastToIntPtrTy
= !MemTy
->isFloatingType();
942 case AtomicExpr::AO__c11_atomic_store
:
943 case AtomicExpr::AO__c11_atomic_exchange
:
944 case AtomicExpr::AO__opencl_atomic_store
:
945 case AtomicExpr::AO__hip_atomic_store
:
946 case AtomicExpr::AO__opencl_atomic_exchange
:
947 case AtomicExpr::AO__hip_atomic_exchange
:
948 case AtomicExpr::AO__atomic_store_n
:
949 case AtomicExpr::AO__atomic_exchange_n
:
950 case AtomicExpr::AO__c11_atomic_fetch_and
:
951 case AtomicExpr::AO__c11_atomic_fetch_or
:
952 case AtomicExpr::AO__c11_atomic_fetch_xor
:
953 case AtomicExpr::AO__c11_atomic_fetch_nand
:
954 case AtomicExpr::AO__opencl_atomic_fetch_and
:
955 case AtomicExpr::AO__opencl_atomic_fetch_or
:
956 case AtomicExpr::AO__opencl_atomic_fetch_xor
:
957 case AtomicExpr::AO__atomic_fetch_and
:
958 case AtomicExpr::AO__hip_atomic_fetch_and
:
959 case AtomicExpr::AO__atomic_fetch_or
:
960 case AtomicExpr::AO__hip_atomic_fetch_or
:
961 case AtomicExpr::AO__atomic_fetch_xor
:
962 case AtomicExpr::AO__hip_atomic_fetch_xor
:
963 case AtomicExpr::AO__atomic_fetch_nand
:
964 case AtomicExpr::AO__atomic_and_fetch
:
965 case AtomicExpr::AO__atomic_or_fetch
:
966 case AtomicExpr::AO__atomic_xor_fetch
:
967 case AtomicExpr::AO__atomic_nand_fetch
:
968 Val1
= EmitValToTemp(*this, E
->getVal1());
972 QualType RValTy
= E
->getType().getUnqualifiedType();
974 // The inlined atomics only function on iN types, where N is a power of 2. We
975 // need to make sure (via temporaries if necessary) that all incoming values
977 LValue AtomicVal
= MakeAddrLValue(Ptr
, AtomicTy
);
978 AtomicInfo
Atomics(*this, AtomicVal
);
980 if (ShouldCastToIntPtrTy
) {
981 Ptr
= Atomics
.castToAtomicIntPointer(Ptr
);
983 Val1
= Atomics
.convertToAtomicIntPointer(Val1
);
985 Val2
= Atomics
.convertToAtomicIntPointer(Val2
);
987 if (Dest
.isValid()) {
988 if (ShouldCastToIntPtrTy
)
989 Dest
= Atomics
.castToAtomicIntPointer(Dest
);
990 } else if (E
->isCmpXChg())
991 Dest
= CreateMemTemp(RValTy
, "cmpxchg.bool");
992 else if (!RValTy
->isVoidType()) {
993 Dest
= Atomics
.CreateTempAlloca();
994 if (ShouldCastToIntPtrTy
)
995 Dest
= Atomics
.castToAtomicIntPointer(Dest
);
998 // Use a library call. See: http://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary .
1000 bool UseOptimizedLibcall
= false;
1001 switch (E
->getOp()) {
1002 case AtomicExpr::AO__c11_atomic_init
:
1003 case AtomicExpr::AO__opencl_atomic_init
:
1004 llvm_unreachable("Already handled above with EmitAtomicInit!");
1006 case AtomicExpr::AO__c11_atomic_fetch_add
:
1007 case AtomicExpr::AO__opencl_atomic_fetch_add
:
1008 case AtomicExpr::AO__atomic_fetch_add
:
1009 case AtomicExpr::AO__hip_atomic_fetch_add
:
1010 case AtomicExpr::AO__c11_atomic_fetch_and
:
1011 case AtomicExpr::AO__opencl_atomic_fetch_and
:
1012 case AtomicExpr::AO__hip_atomic_fetch_and
:
1013 case AtomicExpr::AO__atomic_fetch_and
:
1014 case AtomicExpr::AO__c11_atomic_fetch_or
:
1015 case AtomicExpr::AO__opencl_atomic_fetch_or
:
1016 case AtomicExpr::AO__hip_atomic_fetch_or
:
1017 case AtomicExpr::AO__atomic_fetch_or
:
1018 case AtomicExpr::AO__c11_atomic_fetch_nand
:
1019 case AtomicExpr::AO__atomic_fetch_nand
:
1020 case AtomicExpr::AO__c11_atomic_fetch_sub
:
1021 case AtomicExpr::AO__opencl_atomic_fetch_sub
:
1022 case AtomicExpr::AO__atomic_fetch_sub
:
1023 case AtomicExpr::AO__hip_atomic_fetch_sub
:
1024 case AtomicExpr::AO__c11_atomic_fetch_xor
:
1025 case AtomicExpr::AO__opencl_atomic_fetch_xor
:
1026 case AtomicExpr::AO__opencl_atomic_fetch_min
:
1027 case AtomicExpr::AO__opencl_atomic_fetch_max
:
1028 case AtomicExpr::AO__atomic_fetch_xor
:
1029 case AtomicExpr::AO__hip_atomic_fetch_xor
:
1030 case AtomicExpr::AO__c11_atomic_fetch_max
:
1031 case AtomicExpr::AO__c11_atomic_fetch_min
:
1032 case AtomicExpr::AO__atomic_add_fetch
:
1033 case AtomicExpr::AO__atomic_and_fetch
:
1034 case AtomicExpr::AO__atomic_nand_fetch
:
1035 case AtomicExpr::AO__atomic_or_fetch
:
1036 case AtomicExpr::AO__atomic_sub_fetch
:
1037 case AtomicExpr::AO__atomic_xor_fetch
:
1038 case AtomicExpr::AO__atomic_fetch_max
:
1039 case AtomicExpr::AO__hip_atomic_fetch_max
:
1040 case AtomicExpr::AO__atomic_fetch_min
:
1041 case AtomicExpr::AO__hip_atomic_fetch_min
:
1042 case AtomicExpr::AO__atomic_max_fetch
:
1043 case AtomicExpr::AO__atomic_min_fetch
:
1044 // For these, only library calls for certain sizes exist.
1045 UseOptimizedLibcall
= true;
1048 case AtomicExpr::AO__atomic_load
:
1049 case AtomicExpr::AO__atomic_store
:
1050 case AtomicExpr::AO__atomic_exchange
:
1051 case AtomicExpr::AO__atomic_compare_exchange
:
1052 // Use the generic version if we don't know that the operand will be
1053 // suitably aligned for the optimized version.
1057 case AtomicExpr::AO__c11_atomic_load
:
1058 case AtomicExpr::AO__c11_atomic_store
:
1059 case AtomicExpr::AO__c11_atomic_exchange
:
1060 case AtomicExpr::AO__c11_atomic_compare_exchange_weak
:
1061 case AtomicExpr::AO__c11_atomic_compare_exchange_strong
:
1062 case AtomicExpr::AO__hip_atomic_compare_exchange_strong
:
1063 case AtomicExpr::AO__opencl_atomic_load
:
1064 case AtomicExpr::AO__hip_atomic_load
:
1065 case AtomicExpr::AO__opencl_atomic_store
:
1066 case AtomicExpr::AO__hip_atomic_store
:
1067 case AtomicExpr::AO__opencl_atomic_exchange
:
1068 case AtomicExpr::AO__hip_atomic_exchange
:
1069 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak
:
1070 case AtomicExpr::AO__hip_atomic_compare_exchange_weak
:
1071 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong
:
1072 case AtomicExpr::AO__atomic_load_n
:
1073 case AtomicExpr::AO__atomic_store_n
:
1074 case AtomicExpr::AO__atomic_exchange_n
:
1075 case AtomicExpr::AO__atomic_compare_exchange_n
:
1076 // Only use optimized library calls for sizes for which they exist.
1077 // FIXME: Size == 16 optimized library functions exist too.
1078 if (Size
== 1 || Size
== 2 || Size
== 4 || Size
== 8)
1079 UseOptimizedLibcall
= true;
1084 if (!UseOptimizedLibcall
) {
1085 // For non-optimized library calls, the size is the first parameter
1086 Args
.add(RValue::get(llvm::ConstantInt::get(SizeTy
, Size
)),
1087 getContext().getSizeType());
1089 // Atomic address is the first or second parameter
1090 // The OpenCL atomic library functions only accept pointer arguments to
1091 // generic address space.
1092 auto CastToGenericAddrSpace
= [&](llvm::Value
*V
, QualType PT
) {
1095 auto AS
= PT
->castAs
<PointerType
>()->getPointeeType().getAddressSpace();
1096 if (AS
== LangAS::opencl_generic
)
1098 auto DestAS
= getContext().getTargetAddressSpace(LangAS::opencl_generic
);
1099 auto *DestType
= llvm::PointerType::get(getLLVMContext(), DestAS
);
1101 return getTargetHooks().performAddrSpaceCast(
1102 *this, V
, AS
, LangAS::opencl_generic
, DestType
, false);
1105 Args
.add(RValue::get(CastToGenericAddrSpace(Ptr
.getPointer(),
1106 E
->getPtr()->getType())),
1107 getContext().VoidPtrTy
);
1109 std::string LibCallName
;
1110 QualType LoweredMemTy
=
1111 MemTy
->isPointerType() ? getContext().getIntPtrType() : MemTy
;
1113 bool HaveRetTy
= false;
1114 llvm::Instruction::BinaryOps PostOp
= (llvm::Instruction::BinaryOps
)0;
1115 bool PostOpMinMax
= false;
1116 switch (E
->getOp()) {
1117 case AtomicExpr::AO__c11_atomic_init
:
1118 case AtomicExpr::AO__opencl_atomic_init
:
1119 llvm_unreachable("Already handled!");
1121 // There is only one libcall for compare an exchange, because there is no
1122 // optimisation benefit possible from a libcall version of a weak compare
1124 // bool __atomic_compare_exchange(size_t size, void *mem, void *expected,
1125 // void *desired, int success, int failure)
1126 // bool __atomic_compare_exchange_N(T *mem, T *expected, T desired,
1127 // int success, int failure)
1128 case AtomicExpr::AO__c11_atomic_compare_exchange_weak
:
1129 case AtomicExpr::AO__c11_atomic_compare_exchange_strong
:
1130 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak
:
1131 case AtomicExpr::AO__hip_atomic_compare_exchange_weak
:
1132 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong
:
1133 case AtomicExpr::AO__hip_atomic_compare_exchange_strong
:
1134 case AtomicExpr::AO__atomic_compare_exchange
:
1135 case AtomicExpr::AO__atomic_compare_exchange_n
:
1136 LibCallName
= "__atomic_compare_exchange";
1137 RetTy
= getContext().BoolTy
;
1139 Args
.add(RValue::get(CastToGenericAddrSpace(Val1
.getPointer(),
1140 E
->getVal1()->getType())),
1141 getContext().VoidPtrTy
);
1142 AddDirectArgument(*this, Args
, UseOptimizedLibcall
, Val2
.getPointer(),
1143 MemTy
, E
->getExprLoc(), TInfo
.Width
);
1144 Args
.add(RValue::get(Order
), getContext().IntTy
);
1147 // void __atomic_exchange(size_t size, void *mem, void *val, void *return,
1149 // T __atomic_exchange_N(T *mem, T val, int order)
1150 case AtomicExpr::AO__c11_atomic_exchange
:
1151 case AtomicExpr::AO__opencl_atomic_exchange
:
1152 case AtomicExpr::AO__atomic_exchange_n
:
1153 case AtomicExpr::AO__atomic_exchange
:
1154 case AtomicExpr::AO__hip_atomic_exchange
:
1155 LibCallName
= "__atomic_exchange";
1156 AddDirectArgument(*this, Args
, UseOptimizedLibcall
, Val1
.getPointer(),
1157 MemTy
, E
->getExprLoc(), TInfo
.Width
);
1159 // void __atomic_store(size_t size, void *mem, void *val, int order)
1160 // void __atomic_store_N(T *mem, T val, int order)
1161 case AtomicExpr::AO__c11_atomic_store
:
1162 case AtomicExpr::AO__opencl_atomic_store
:
1163 case AtomicExpr::AO__hip_atomic_store
:
1164 case AtomicExpr::AO__atomic_store
:
1165 case AtomicExpr::AO__atomic_store_n
:
1166 LibCallName
= "__atomic_store";
1167 RetTy
= getContext().VoidTy
;
1169 AddDirectArgument(*this, Args
, UseOptimizedLibcall
, Val1
.getPointer(),
1170 MemTy
, E
->getExprLoc(), TInfo
.Width
);
1172 // void __atomic_load(size_t size, void *mem, void *return, int order)
1173 // T __atomic_load_N(T *mem, int order)
1174 case AtomicExpr::AO__c11_atomic_load
:
1175 case AtomicExpr::AO__opencl_atomic_load
:
1176 case AtomicExpr::AO__hip_atomic_load
:
1177 case AtomicExpr::AO__atomic_load
:
1178 case AtomicExpr::AO__atomic_load_n
:
1179 LibCallName
= "__atomic_load";
1181 // T __atomic_add_fetch_N(T *mem, T val, int order)
1182 // T __atomic_fetch_add_N(T *mem, T val, int order)
1183 case AtomicExpr::AO__atomic_add_fetch
:
1184 PostOp
= llvm::Instruction::Add
;
1186 case AtomicExpr::AO__c11_atomic_fetch_add
:
1187 case AtomicExpr::AO__opencl_atomic_fetch_add
:
1188 case AtomicExpr::AO__atomic_fetch_add
:
1189 case AtomicExpr::AO__hip_atomic_fetch_add
:
1190 LibCallName
= "__atomic_fetch_add";
1191 AddDirectArgument(*this, Args
, UseOptimizedLibcall
, Val1
.getPointer(),
1192 LoweredMemTy
, E
->getExprLoc(), TInfo
.Width
);
1194 // T __atomic_and_fetch_N(T *mem, T val, int order)
1195 // T __atomic_fetch_and_N(T *mem, T val, int order)
1196 case AtomicExpr::AO__atomic_and_fetch
:
1197 PostOp
= llvm::Instruction::And
;
1199 case AtomicExpr::AO__c11_atomic_fetch_and
:
1200 case AtomicExpr::AO__opencl_atomic_fetch_and
:
1201 case AtomicExpr::AO__hip_atomic_fetch_and
:
1202 case AtomicExpr::AO__atomic_fetch_and
:
1203 LibCallName
= "__atomic_fetch_and";
1204 AddDirectArgument(*this, Args
, UseOptimizedLibcall
, Val1
.getPointer(),
1205 MemTy
, E
->getExprLoc(), TInfo
.Width
);
1207 // T __atomic_or_fetch_N(T *mem, T val, int order)
1208 // T __atomic_fetch_or_N(T *mem, T val, int order)
1209 case AtomicExpr::AO__atomic_or_fetch
:
1210 PostOp
= llvm::Instruction::Or
;
1212 case AtomicExpr::AO__c11_atomic_fetch_or
:
1213 case AtomicExpr::AO__opencl_atomic_fetch_or
:
1214 case AtomicExpr::AO__hip_atomic_fetch_or
:
1215 case AtomicExpr::AO__atomic_fetch_or
:
1216 LibCallName
= "__atomic_fetch_or";
1217 AddDirectArgument(*this, Args
, UseOptimizedLibcall
, Val1
.getPointer(),
1218 MemTy
, E
->getExprLoc(), TInfo
.Width
);
1220 // T __atomic_sub_fetch_N(T *mem, T val, int order)
1221 // T __atomic_fetch_sub_N(T *mem, T val, int order)
1222 case AtomicExpr::AO__atomic_sub_fetch
:
1223 PostOp
= llvm::Instruction::Sub
;
1225 case AtomicExpr::AO__c11_atomic_fetch_sub
:
1226 case AtomicExpr::AO__opencl_atomic_fetch_sub
:
1227 case AtomicExpr::AO__hip_atomic_fetch_sub
:
1228 case AtomicExpr::AO__atomic_fetch_sub
:
1229 LibCallName
= "__atomic_fetch_sub";
1230 AddDirectArgument(*this, Args
, UseOptimizedLibcall
, Val1
.getPointer(),
1231 LoweredMemTy
, E
->getExprLoc(), TInfo
.Width
);
1233 // T __atomic_xor_fetch_N(T *mem, T val, int order)
1234 // T __atomic_fetch_xor_N(T *mem, T val, int order)
1235 case AtomicExpr::AO__atomic_xor_fetch
:
1236 PostOp
= llvm::Instruction::Xor
;
1238 case AtomicExpr::AO__c11_atomic_fetch_xor
:
1239 case AtomicExpr::AO__opencl_atomic_fetch_xor
:
1240 case AtomicExpr::AO__hip_atomic_fetch_xor
:
1241 case AtomicExpr::AO__atomic_fetch_xor
:
1242 LibCallName
= "__atomic_fetch_xor";
1243 AddDirectArgument(*this, Args
, UseOptimizedLibcall
, Val1
.getPointer(),
1244 MemTy
, E
->getExprLoc(), TInfo
.Width
);
1246 case AtomicExpr::AO__atomic_min_fetch
:
1247 PostOpMinMax
= true;
1249 case AtomicExpr::AO__c11_atomic_fetch_min
:
1250 case AtomicExpr::AO__atomic_fetch_min
:
1251 case AtomicExpr::AO__hip_atomic_fetch_min
:
1252 case AtomicExpr::AO__opencl_atomic_fetch_min
:
1253 LibCallName
= E
->getValueType()->isSignedIntegerType()
1254 ? "__atomic_fetch_min"
1255 : "__atomic_fetch_umin";
1256 AddDirectArgument(*this, Args
, UseOptimizedLibcall
, Val1
.getPointer(),
1257 LoweredMemTy
, E
->getExprLoc(), TInfo
.Width
);
1259 case AtomicExpr::AO__atomic_max_fetch
:
1260 PostOpMinMax
= true;
1262 case AtomicExpr::AO__c11_atomic_fetch_max
:
1263 case AtomicExpr::AO__atomic_fetch_max
:
1264 case AtomicExpr::AO__hip_atomic_fetch_max
:
1265 case AtomicExpr::AO__opencl_atomic_fetch_max
:
1266 LibCallName
= E
->getValueType()->isSignedIntegerType()
1267 ? "__atomic_fetch_max"
1268 : "__atomic_fetch_umax";
1269 AddDirectArgument(*this, Args
, UseOptimizedLibcall
, Val1
.getPointer(),
1270 LoweredMemTy
, E
->getExprLoc(), TInfo
.Width
);
1272 // T __atomic_nand_fetch_N(T *mem, T val, int order)
1273 // T __atomic_fetch_nand_N(T *mem, T val, int order)
1274 case AtomicExpr::AO__atomic_nand_fetch
:
1275 PostOp
= llvm::Instruction::And
; // the NOT is special cased below
1277 case AtomicExpr::AO__c11_atomic_fetch_nand
:
1278 case AtomicExpr::AO__atomic_fetch_nand
:
1279 LibCallName
= "__atomic_fetch_nand";
1280 AddDirectArgument(*this, Args
, UseOptimizedLibcall
, Val1
.getPointer(),
1281 MemTy
, E
->getExprLoc(), TInfo
.Width
);
1285 if (E
->isOpenCL()) {
1286 LibCallName
= std::string("__opencl") +
1287 StringRef(LibCallName
).drop_front(1).str();
1290 // Optimized functions have the size in their name.
1291 if (UseOptimizedLibcall
)
1292 LibCallName
+= "_" + llvm::utostr(Size
);
1293 // By default, assume we return a value of the atomic type.
1295 if (UseOptimizedLibcall
) {
1296 // Value is returned directly.
1297 // The function returns an appropriately sized integer type.
1298 RetTy
= getContext().getIntTypeForBitwidth(
1299 getContext().toBits(TInfo
.Width
), /*Signed=*/false);
1301 // Value is returned through parameter before the order.
1302 RetTy
= getContext().VoidTy
;
1303 Args
.add(RValue::get(Dest
.getPointer()), getContext().VoidPtrTy
);
1306 // order is always the last parameter
1307 Args
.add(RValue::get(Order
),
1308 getContext().IntTy
);
1310 Args
.add(RValue::get(Scope
), getContext().IntTy
);
1312 // PostOp is only needed for the atomic_*_fetch operations, and
1313 // thus is only needed for and implemented in the
1314 // UseOptimizedLibcall codepath.
1315 assert(UseOptimizedLibcall
|| (!PostOp
&& !PostOpMinMax
));
1317 RValue Res
= emitAtomicLibcall(*this, LibCallName
, RetTy
, Args
);
1318 // The value is returned directly from the libcall.
1322 // The value is returned directly for optimized libcalls but the expr
1323 // provided an out-param.
1324 if (UseOptimizedLibcall
&& Res
.getScalarVal()) {
1325 llvm::Value
*ResVal
= Res
.getScalarVal();
1327 llvm::Value
*LoadVal1
= Args
[1].getRValue(*this).getScalarVal();
1328 ResVal
= EmitPostAtomicMinMax(Builder
, E
->getOp(),
1329 E
->getValueType()->isSignedIntegerType(),
1331 } else if (PostOp
) {
1332 llvm::Value
*LoadVal1
= Args
[1].getRValue(*this).getScalarVal();
1333 ResVal
= Builder
.CreateBinOp(PostOp
, ResVal
, LoadVal1
);
1335 if (E
->getOp() == AtomicExpr::AO__atomic_nand_fetch
)
1336 ResVal
= Builder
.CreateNot(ResVal
);
1338 Builder
.CreateStore(ResVal
, Dest
.withElementType(ResVal
->getType()));
1341 if (RValTy
->isVoidType())
1342 return RValue::get(nullptr);
1344 return convertTempToRValue(Dest
.withElementType(ConvertTypeForMem(RValTy
)),
1345 RValTy
, E
->getExprLoc());
1348 bool IsStore
= E
->getOp() == AtomicExpr::AO__c11_atomic_store
||
1349 E
->getOp() == AtomicExpr::AO__opencl_atomic_store
||
1350 E
->getOp() == AtomicExpr::AO__hip_atomic_store
||
1351 E
->getOp() == AtomicExpr::AO__atomic_store
||
1352 E
->getOp() == AtomicExpr::AO__atomic_store_n
;
1353 bool IsLoad
= E
->getOp() == AtomicExpr::AO__c11_atomic_load
||
1354 E
->getOp() == AtomicExpr::AO__opencl_atomic_load
||
1355 E
->getOp() == AtomicExpr::AO__hip_atomic_load
||
1356 E
->getOp() == AtomicExpr::AO__atomic_load
||
1357 E
->getOp() == AtomicExpr::AO__atomic_load_n
;
1359 if (isa
<llvm::ConstantInt
>(Order
)) {
1360 auto ord
= cast
<llvm::ConstantInt
>(Order
)->getZExtValue();
1361 // We should not ever get to a case where the ordering isn't a valid C ABI
1362 // value, but it's hard to enforce that in general.
1363 if (llvm::isValidAtomicOrderingCABI(ord
))
1364 switch ((llvm::AtomicOrderingCABI
)ord
) {
1365 case llvm::AtomicOrderingCABI::relaxed
:
1366 EmitAtomicOp(*this, E
, Dest
, Ptr
, Val1
, Val2
, IsWeak
, OrderFail
, Size
,
1367 llvm::AtomicOrdering::Monotonic
, Scope
);
1369 case llvm::AtomicOrderingCABI::consume
:
1370 case llvm::AtomicOrderingCABI::acquire
:
1372 break; // Avoid crashing on code with undefined behavior
1373 EmitAtomicOp(*this, E
, Dest
, Ptr
, Val1
, Val2
, IsWeak
, OrderFail
, Size
,
1374 llvm::AtomicOrdering::Acquire
, Scope
);
1376 case llvm::AtomicOrderingCABI::release
:
1378 break; // Avoid crashing on code with undefined behavior
1379 EmitAtomicOp(*this, E
, Dest
, Ptr
, Val1
, Val2
, IsWeak
, OrderFail
, Size
,
1380 llvm::AtomicOrdering::Release
, Scope
);
1382 case llvm::AtomicOrderingCABI::acq_rel
:
1383 if (IsLoad
|| IsStore
)
1384 break; // Avoid crashing on code with undefined behavior
1385 EmitAtomicOp(*this, E
, Dest
, Ptr
, Val1
, Val2
, IsWeak
, OrderFail
, Size
,
1386 llvm::AtomicOrdering::AcquireRelease
, Scope
);
1388 case llvm::AtomicOrderingCABI::seq_cst
:
1389 EmitAtomicOp(*this, E
, Dest
, Ptr
, Val1
, Val2
, IsWeak
, OrderFail
, Size
,
1390 llvm::AtomicOrdering::SequentiallyConsistent
, Scope
);
1393 if (RValTy
->isVoidType())
1394 return RValue::get(nullptr);
1396 return convertTempToRValue(Dest
.withElementType(ConvertTypeForMem(RValTy
)),
1397 RValTy
, E
->getExprLoc());
1400 // Long case, when Order isn't obviously constant.
1402 // Create all the relevant BB's
1403 llvm::BasicBlock
*MonotonicBB
= nullptr, *AcquireBB
= nullptr,
1404 *ReleaseBB
= nullptr, *AcqRelBB
= nullptr,
1405 *SeqCstBB
= nullptr;
1406 MonotonicBB
= createBasicBlock("monotonic", CurFn
);
1408 AcquireBB
= createBasicBlock("acquire", CurFn
);
1410 ReleaseBB
= createBasicBlock("release", CurFn
);
1411 if (!IsLoad
&& !IsStore
)
1412 AcqRelBB
= createBasicBlock("acqrel", CurFn
);
1413 SeqCstBB
= createBasicBlock("seqcst", CurFn
);
1414 llvm::BasicBlock
*ContBB
= createBasicBlock("atomic.continue", CurFn
);
1416 // Create the switch for the split
1417 // MonotonicBB is arbitrarily chosen as the default case; in practice, this
1418 // doesn't matter unless someone is crazy enough to use something that
1419 // doesn't fold to a constant for the ordering.
1420 Order
= Builder
.CreateIntCast(Order
, Builder
.getInt32Ty(), false);
1421 llvm::SwitchInst
*SI
= Builder
.CreateSwitch(Order
, MonotonicBB
);
1423 // Emit all the different atomics
1424 Builder
.SetInsertPoint(MonotonicBB
);
1425 EmitAtomicOp(*this, E
, Dest
, Ptr
, Val1
, Val2
, IsWeak
, OrderFail
, Size
,
1426 llvm::AtomicOrdering::Monotonic
, Scope
);
1427 Builder
.CreateBr(ContBB
);
1429 Builder
.SetInsertPoint(AcquireBB
);
1430 EmitAtomicOp(*this, E
, Dest
, Ptr
, Val1
, Val2
, IsWeak
, OrderFail
, Size
,
1431 llvm::AtomicOrdering::Acquire
, Scope
);
1432 Builder
.CreateBr(ContBB
);
1433 SI
->addCase(Builder
.getInt32((int)llvm::AtomicOrderingCABI::consume
),
1435 SI
->addCase(Builder
.getInt32((int)llvm::AtomicOrderingCABI::acquire
),
1439 Builder
.SetInsertPoint(ReleaseBB
);
1440 EmitAtomicOp(*this, E
, Dest
, Ptr
, Val1
, Val2
, IsWeak
, OrderFail
, Size
,
1441 llvm::AtomicOrdering::Release
, Scope
);
1442 Builder
.CreateBr(ContBB
);
1443 SI
->addCase(Builder
.getInt32((int)llvm::AtomicOrderingCABI::release
),
1446 if (!IsLoad
&& !IsStore
) {
1447 Builder
.SetInsertPoint(AcqRelBB
);
1448 EmitAtomicOp(*this, E
, Dest
, Ptr
, Val1
, Val2
, IsWeak
, OrderFail
, Size
,
1449 llvm::AtomicOrdering::AcquireRelease
, Scope
);
1450 Builder
.CreateBr(ContBB
);
1451 SI
->addCase(Builder
.getInt32((int)llvm::AtomicOrderingCABI::acq_rel
),
1454 Builder
.SetInsertPoint(SeqCstBB
);
1455 EmitAtomicOp(*this, E
, Dest
, Ptr
, Val1
, Val2
, IsWeak
, OrderFail
, Size
,
1456 llvm::AtomicOrdering::SequentiallyConsistent
, Scope
);
1457 Builder
.CreateBr(ContBB
);
1458 SI
->addCase(Builder
.getInt32((int)llvm::AtomicOrderingCABI::seq_cst
),
1461 // Cleanup and return
1462 Builder
.SetInsertPoint(ContBB
);
1463 if (RValTy
->isVoidType())
1464 return RValue::get(nullptr);
1466 assert(Atomics
.getValueSizeInBits() <= Atomics
.getAtomicSizeInBits());
1467 return convertTempToRValue(Dest
.withElementType(ConvertTypeForMem(RValTy
)),
1468 RValTy
, E
->getExprLoc());
1471 Address
AtomicInfo::castToAtomicIntPointer(Address addr
) const {
1472 llvm::IntegerType
*ty
=
1473 llvm::IntegerType::get(CGF
.getLLVMContext(), AtomicSizeInBits
);
1474 return addr
.withElementType(ty
);
1477 Address
AtomicInfo::convertToAtomicIntPointer(Address Addr
) const {
1478 llvm::Type
*Ty
= Addr
.getElementType();
1479 uint64_t SourceSizeInBits
= CGF
.CGM
.getDataLayout().getTypeSizeInBits(Ty
);
1480 if (SourceSizeInBits
!= AtomicSizeInBits
) {
1481 Address Tmp
= CreateTempAlloca();
1482 CGF
.Builder
.CreateMemCpy(Tmp
, Addr
,
1483 std::min(AtomicSizeInBits
, SourceSizeInBits
) / 8);
1487 return castToAtomicIntPointer(Addr
);
1490 RValue
AtomicInfo::convertAtomicTempToRValue(Address addr
,
1491 AggValueSlot resultSlot
,
1493 bool asValue
) const {
1494 if (LVal
.isSimple()) {
1495 if (EvaluationKind
== TEK_Aggregate
)
1496 return resultSlot
.asRValue();
1498 // Drill into the padding structure if we have one.
1500 addr
= CGF
.Builder
.CreateStructGEP(addr
, 0);
1502 // Otherwise, just convert the temporary to an r-value using the
1503 // normal conversion routine.
1504 return CGF
.convertTempToRValue(addr
, getValueType(), loc
);
1507 // Get RValue from temp memory as atomic for non-simple lvalues
1508 return RValue::get(CGF
.Builder
.CreateLoad(addr
));
1509 if (LVal
.isBitField())
1510 return CGF
.EmitLoadOfBitfieldLValue(
1511 LValue::MakeBitfield(addr
, LVal
.getBitFieldInfo(), LVal
.getType(),
1512 LVal
.getBaseInfo(), TBAAAccessInfo()), loc
);
1513 if (LVal
.isVectorElt())
1514 return CGF
.EmitLoadOfLValue(
1515 LValue::MakeVectorElt(addr
, LVal
.getVectorIdx(), LVal
.getType(),
1516 LVal
.getBaseInfo(), TBAAAccessInfo()), loc
);
1517 assert(LVal
.isExtVectorElt());
1518 return CGF
.EmitLoadOfExtVectorElementLValue(LValue::MakeExtVectorElt(
1519 addr
, LVal
.getExtVectorElts(), LVal
.getType(),
1520 LVal
.getBaseInfo(), TBAAAccessInfo()));
1523 RValue
AtomicInfo::ConvertIntToValueOrAtomic(llvm::Value
*IntVal
,
1524 AggValueSlot ResultSlot
,
1526 bool AsValue
) const {
1527 // Try not to in some easy cases.
1528 assert(IntVal
->getType()->isIntegerTy() && "Expected integer value");
1529 if (getEvaluationKind() == TEK_Scalar
&&
1530 (((!LVal
.isBitField() ||
1531 LVal
.getBitFieldInfo().Size
== ValueSizeInBits
) &&
1534 auto *ValTy
= AsValue
1535 ? CGF
.ConvertTypeForMem(ValueTy
)
1536 : getAtomicAddress().getElementType();
1537 if (ValTy
->isIntegerTy()) {
1538 assert(IntVal
->getType() == ValTy
&& "Different integer types.");
1539 return RValue::get(CGF
.EmitFromMemory(IntVal
, ValueTy
));
1540 } else if (ValTy
->isPointerTy())
1541 return RValue::get(CGF
.Builder
.CreateIntToPtr(IntVal
, ValTy
));
1542 else if (llvm::CastInst::isBitCastable(IntVal
->getType(), ValTy
))
1543 return RValue::get(CGF
.Builder
.CreateBitCast(IntVal
, ValTy
));
1546 // Create a temporary. This needs to be big enough to hold the
1548 Address Temp
= Address::invalid();
1549 bool TempIsVolatile
= false;
1550 if (AsValue
&& getEvaluationKind() == TEK_Aggregate
) {
1551 assert(!ResultSlot
.isIgnored());
1552 Temp
= ResultSlot
.getAddress();
1553 TempIsVolatile
= ResultSlot
.isVolatile();
1555 Temp
= CreateTempAlloca();
1558 // Slam the integer into the temporary.
1559 Address CastTemp
= castToAtomicIntPointer(Temp
);
1560 CGF
.Builder
.CreateStore(IntVal
, CastTemp
)
1561 ->setVolatile(TempIsVolatile
);
1563 return convertAtomicTempToRValue(Temp
, ResultSlot
, Loc
, AsValue
);
1566 void AtomicInfo::EmitAtomicLoadLibcall(llvm::Value
*AddForLoaded
,
1567 llvm::AtomicOrdering AO
, bool) {
1568 // void __atomic_load(size_t size, void *mem, void *return, int order);
1570 Args
.add(RValue::get(getAtomicSizeValue()), CGF
.getContext().getSizeType());
1571 Args
.add(RValue::get(getAtomicPointer()), CGF
.getContext().VoidPtrTy
);
1572 Args
.add(RValue::get(AddForLoaded
), CGF
.getContext().VoidPtrTy
);
1574 RValue::get(llvm::ConstantInt::get(CGF
.IntTy
, (int)llvm::toCABI(AO
))),
1575 CGF
.getContext().IntTy
);
1576 emitAtomicLibcall(CGF
, "__atomic_load", CGF
.getContext().VoidTy
, Args
);
1579 llvm::Value
*AtomicInfo::EmitAtomicLoadOp(llvm::AtomicOrdering AO
,
1581 // Okay, we're doing this natively.
1582 Address Addr
= getAtomicAddressAsAtomicIntPointer();
1583 llvm::LoadInst
*Load
= CGF
.Builder
.CreateLoad(Addr
, "atomic-load");
1584 Load
->setAtomic(AO
);
1586 // Other decoration.
1588 Load
->setVolatile(true);
1589 CGF
.CGM
.DecorateInstructionWithTBAA(Load
, LVal
.getTBAAInfo());
1593 /// An LValue is a candidate for having its loads and stores be made atomic if
1594 /// we are operating under /volatile:ms *and* the LValue itself is volatile and
1595 /// performing such an operation can be performed without a libcall.
1596 bool CodeGenFunction::LValueIsSuitableForInlineAtomic(LValue LV
) {
1597 if (!CGM
.getLangOpts().MSVolatile
) return false;
1598 AtomicInfo
AI(*this, LV
);
1599 bool IsVolatile
= LV
.isVolatile() || hasVolatileMember(LV
.getType());
1600 // An atomic is inline if we don't need to use a libcall.
1601 bool AtomicIsInline
= !AI
.shouldUseLibcall();
1602 // MSVC doesn't seem to do this for types wider than a pointer.
1603 if (getContext().getTypeSize(LV
.getType()) >
1604 getContext().getTypeSize(getContext().getIntPtrType()))
1606 return IsVolatile
&& AtomicIsInline
;
1609 RValue
CodeGenFunction::EmitAtomicLoad(LValue LV
, SourceLocation SL
,
1610 AggValueSlot Slot
) {
1611 llvm::AtomicOrdering AO
;
1612 bool IsVolatile
= LV
.isVolatileQualified();
1613 if (LV
.getType()->isAtomicType()) {
1614 AO
= llvm::AtomicOrdering::SequentiallyConsistent
;
1616 AO
= llvm::AtomicOrdering::Acquire
;
1619 return EmitAtomicLoad(LV
, SL
, AO
, IsVolatile
, Slot
);
1622 RValue
AtomicInfo::EmitAtomicLoad(AggValueSlot ResultSlot
, SourceLocation Loc
,
1623 bool AsValue
, llvm::AtomicOrdering AO
,
1625 // Check whether we should use a library call.
1626 if (shouldUseLibcall()) {
1627 Address TempAddr
= Address::invalid();
1628 if (LVal
.isSimple() && !ResultSlot
.isIgnored()) {
1629 assert(getEvaluationKind() == TEK_Aggregate
);
1630 TempAddr
= ResultSlot
.getAddress();
1632 TempAddr
= CreateTempAlloca();
1634 EmitAtomicLoadLibcall(TempAddr
.getPointer(), AO
, IsVolatile
);
1636 // Okay, turn that back into the original value or whole atomic (for
1637 // non-simple lvalues) type.
1638 return convertAtomicTempToRValue(TempAddr
, ResultSlot
, Loc
, AsValue
);
1641 // Okay, we're doing this natively.
1642 auto *Load
= EmitAtomicLoadOp(AO
, IsVolatile
);
1644 // If we're ignoring an aggregate return, don't do anything.
1645 if (getEvaluationKind() == TEK_Aggregate
&& ResultSlot
.isIgnored())
1646 return RValue::getAggregate(Address::invalid(), false);
1648 // Okay, turn that back into the original value or atomic (for non-simple
1650 return ConvertIntToValueOrAtomic(Load
, ResultSlot
, Loc
, AsValue
);
1653 /// Emit a load from an l-value of atomic type. Note that the r-value
1654 /// we produce is an r-value of the atomic *value* type.
1655 RValue
CodeGenFunction::EmitAtomicLoad(LValue src
, SourceLocation loc
,
1656 llvm::AtomicOrdering AO
, bool IsVolatile
,
1657 AggValueSlot resultSlot
) {
1658 AtomicInfo
Atomics(*this, src
);
1659 return Atomics
.EmitAtomicLoad(resultSlot
, loc
, /*AsValue=*/true, AO
,
1663 /// Copy an r-value into memory as part of storing to an atomic type.
1664 /// This needs to create a bit-pattern suitable for atomic operations.
1665 void AtomicInfo::emitCopyIntoMemory(RValue rvalue
) const {
1666 assert(LVal
.isSimple());
1667 // If we have an r-value, the rvalue should be of the atomic type,
1668 // which means that the caller is responsible for having zeroed
1669 // any padding. Just do an aggregate copy of that type.
1670 if (rvalue
.isAggregate()) {
1671 LValue Dest
= CGF
.MakeAddrLValue(getAtomicAddress(), getAtomicType());
1672 LValue Src
= CGF
.MakeAddrLValue(rvalue
.getAggregateAddress(),
1674 bool IsVolatile
= rvalue
.isVolatileQualified() ||
1675 LVal
.isVolatileQualified();
1676 CGF
.EmitAggregateCopy(Dest
, Src
, getAtomicType(),
1677 AggValueSlot::DoesNotOverlap
, IsVolatile
);
1681 // Okay, otherwise we're copying stuff.
1683 // Zero out the buffer if necessary.
1684 emitMemSetZeroIfNecessary();
1686 // Drill past the padding if present.
1687 LValue TempLVal
= projectValue();
1689 // Okay, store the rvalue in.
1690 if (rvalue
.isScalar()) {
1691 CGF
.EmitStoreOfScalar(rvalue
.getScalarVal(), TempLVal
, /*init*/ true);
1693 CGF
.EmitStoreOfComplex(rvalue
.getComplexVal(), TempLVal
, /*init*/ true);
1698 /// Materialize an r-value into memory for the purposes of storing it
1699 /// to an atomic type.
1700 Address
AtomicInfo::materializeRValue(RValue rvalue
) const {
1701 // Aggregate r-values are already in memory, and EmitAtomicStore
1702 // requires them to be values of the atomic type.
1703 if (rvalue
.isAggregate())
1704 return rvalue
.getAggregateAddress();
1706 // Otherwise, make a temporary and materialize into it.
1707 LValue TempLV
= CGF
.MakeAddrLValue(CreateTempAlloca(), getAtomicType());
1708 AtomicInfo
Atomics(CGF
, TempLV
);
1709 Atomics
.emitCopyIntoMemory(rvalue
);
1710 return TempLV
.getAddress(CGF
);
1713 llvm::Value
*AtomicInfo::convertRValueToInt(RValue RVal
) const {
1714 // If we've got a scalar value of the right size, try to avoid going
1716 if (RVal
.isScalar() && (!hasPadding() || !LVal
.isSimple())) {
1717 llvm::Value
*Value
= RVal
.getScalarVal();
1718 if (isa
<llvm::IntegerType
>(Value
->getType()))
1719 return CGF
.EmitToMemory(Value
, ValueTy
);
1721 llvm::IntegerType
*InputIntTy
= llvm::IntegerType::get(
1722 CGF
.getLLVMContext(),
1723 LVal
.isSimple() ? getValueSizeInBits() : getAtomicSizeInBits());
1724 if (isa
<llvm::PointerType
>(Value
->getType()))
1725 return CGF
.Builder
.CreatePtrToInt(Value
, InputIntTy
);
1726 else if (llvm::BitCastInst::isBitCastable(Value
->getType(), InputIntTy
))
1727 return CGF
.Builder
.CreateBitCast(Value
, InputIntTy
);
1730 // Otherwise, we need to go through memory.
1731 // Put the r-value in memory.
1732 Address Addr
= materializeRValue(RVal
);
1734 // Cast the temporary to the atomic int type and pull a value out.
1735 Addr
= castToAtomicIntPointer(Addr
);
1736 return CGF
.Builder
.CreateLoad(Addr
);
1739 std::pair
<llvm::Value
*, llvm::Value
*> AtomicInfo::EmitAtomicCompareExchangeOp(
1740 llvm::Value
*ExpectedVal
, llvm::Value
*DesiredVal
,
1741 llvm::AtomicOrdering Success
, llvm::AtomicOrdering Failure
, bool IsWeak
) {
1742 // Do the atomic store.
1743 Address Addr
= getAtomicAddressAsAtomicIntPointer();
1744 auto *Inst
= CGF
.Builder
.CreateAtomicCmpXchg(Addr
.getPointer(),
1745 ExpectedVal
, DesiredVal
,
1747 // Other decoration.
1748 Inst
->setVolatile(LVal
.isVolatileQualified());
1749 Inst
->setWeak(IsWeak
);
1751 // Okay, turn that back into the original value type.
1752 auto *PreviousVal
= CGF
.Builder
.CreateExtractValue(Inst
, /*Idxs=*/0);
1753 auto *SuccessFailureVal
= CGF
.Builder
.CreateExtractValue(Inst
, /*Idxs=*/1);
1754 return std::make_pair(PreviousVal
, SuccessFailureVal
);
1758 AtomicInfo::EmitAtomicCompareExchangeLibcall(llvm::Value
*ExpectedAddr
,
1759 llvm::Value
*DesiredAddr
,
1760 llvm::AtomicOrdering Success
,
1761 llvm::AtomicOrdering Failure
) {
1762 // bool __atomic_compare_exchange(size_t size, void *obj, void *expected,
1763 // void *desired, int success, int failure);
1765 Args
.add(RValue::get(getAtomicSizeValue()), CGF
.getContext().getSizeType());
1766 Args
.add(RValue::get(getAtomicPointer()), CGF
.getContext().VoidPtrTy
);
1767 Args
.add(RValue::get(ExpectedAddr
), CGF
.getContext().VoidPtrTy
);
1768 Args
.add(RValue::get(DesiredAddr
), CGF
.getContext().VoidPtrTy
);
1769 Args
.add(RValue::get(
1770 llvm::ConstantInt::get(CGF
.IntTy
, (int)llvm::toCABI(Success
))),
1771 CGF
.getContext().IntTy
);
1772 Args
.add(RValue::get(
1773 llvm::ConstantInt::get(CGF
.IntTy
, (int)llvm::toCABI(Failure
))),
1774 CGF
.getContext().IntTy
);
1775 auto SuccessFailureRVal
= emitAtomicLibcall(CGF
, "__atomic_compare_exchange",
1776 CGF
.getContext().BoolTy
, Args
);
1778 return SuccessFailureRVal
.getScalarVal();
1781 std::pair
<RValue
, llvm::Value
*> AtomicInfo::EmitAtomicCompareExchange(
1782 RValue Expected
, RValue Desired
, llvm::AtomicOrdering Success
,
1783 llvm::AtomicOrdering Failure
, bool IsWeak
) {
1784 // Check whether we should use a library call.
1785 if (shouldUseLibcall()) {
1786 // Produce a source address.
1787 Address ExpectedAddr
= materializeRValue(Expected
);
1788 Address DesiredAddr
= materializeRValue(Desired
);
1789 auto *Res
= EmitAtomicCompareExchangeLibcall(ExpectedAddr
.getPointer(),
1790 DesiredAddr
.getPointer(),
1792 return std::make_pair(
1793 convertAtomicTempToRValue(ExpectedAddr
, AggValueSlot::ignored(),
1794 SourceLocation(), /*AsValue=*/false),
1798 // If we've got a scalar value of the right size, try to avoid going
1800 auto *ExpectedVal
= convertRValueToInt(Expected
);
1801 auto *DesiredVal
= convertRValueToInt(Desired
);
1802 auto Res
= EmitAtomicCompareExchangeOp(ExpectedVal
, DesiredVal
, Success
,
1804 return std::make_pair(
1805 ConvertIntToValueOrAtomic(Res
.first
, AggValueSlot::ignored(),
1806 SourceLocation(), /*AsValue=*/false),
1811 EmitAtomicUpdateValue(CodeGenFunction
&CGF
, AtomicInfo
&Atomics
, RValue OldRVal
,
1812 const llvm::function_ref
<RValue(RValue
)> &UpdateOp
,
1813 Address DesiredAddr
) {
1815 LValue AtomicLVal
= Atomics
.getAtomicLValue();
1817 if (AtomicLVal
.isSimple()) {
1819 DesiredLVal
= CGF
.MakeAddrLValue(DesiredAddr
, AtomicLVal
.getType());
1821 // Build new lvalue for temp address.
1822 Address Ptr
= Atomics
.materializeRValue(OldRVal
);
1824 if (AtomicLVal
.isBitField()) {
1826 LValue::MakeBitfield(Ptr
, AtomicLVal
.getBitFieldInfo(),
1827 AtomicLVal
.getType(),
1828 AtomicLVal
.getBaseInfo(),
1829 AtomicLVal
.getTBAAInfo());
1831 LValue::MakeBitfield(DesiredAddr
, AtomicLVal
.getBitFieldInfo(),
1832 AtomicLVal
.getType(), AtomicLVal
.getBaseInfo(),
1833 AtomicLVal
.getTBAAInfo());
1834 } else if (AtomicLVal
.isVectorElt()) {
1835 UpdateLVal
= LValue::MakeVectorElt(Ptr
, AtomicLVal
.getVectorIdx(),
1836 AtomicLVal
.getType(),
1837 AtomicLVal
.getBaseInfo(),
1838 AtomicLVal
.getTBAAInfo());
1839 DesiredLVal
= LValue::MakeVectorElt(
1840 DesiredAddr
, AtomicLVal
.getVectorIdx(), AtomicLVal
.getType(),
1841 AtomicLVal
.getBaseInfo(), AtomicLVal
.getTBAAInfo());
1843 assert(AtomicLVal
.isExtVectorElt());
1844 UpdateLVal
= LValue::MakeExtVectorElt(Ptr
, AtomicLVal
.getExtVectorElts(),
1845 AtomicLVal
.getType(),
1846 AtomicLVal
.getBaseInfo(),
1847 AtomicLVal
.getTBAAInfo());
1848 DesiredLVal
= LValue::MakeExtVectorElt(
1849 DesiredAddr
, AtomicLVal
.getExtVectorElts(), AtomicLVal
.getType(),
1850 AtomicLVal
.getBaseInfo(), AtomicLVal
.getTBAAInfo());
1852 UpRVal
= CGF
.EmitLoadOfLValue(UpdateLVal
, SourceLocation());
1854 // Store new value in the corresponding memory area.
1855 RValue NewRVal
= UpdateOp(UpRVal
);
1856 if (NewRVal
.isScalar()) {
1857 CGF
.EmitStoreThroughLValue(NewRVal
, DesiredLVal
);
1859 assert(NewRVal
.isComplex());
1860 CGF
.EmitStoreOfComplex(NewRVal
.getComplexVal(), DesiredLVal
,
1865 void AtomicInfo::EmitAtomicUpdateLibcall(
1866 llvm::AtomicOrdering AO
, const llvm::function_ref
<RValue(RValue
)> &UpdateOp
,
1868 auto Failure
= llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO
);
1870 Address ExpectedAddr
= CreateTempAlloca();
1872 EmitAtomicLoadLibcall(ExpectedAddr
.getPointer(), AO
, IsVolatile
);
1873 auto *ContBB
= CGF
.createBasicBlock("atomic_cont");
1874 auto *ExitBB
= CGF
.createBasicBlock("atomic_exit");
1875 CGF
.EmitBlock(ContBB
);
1876 Address DesiredAddr
= CreateTempAlloca();
1877 if ((LVal
.isBitField() && BFI
.Size
!= ValueSizeInBits
) ||
1878 requiresMemSetZero(getAtomicAddress().getElementType())) {
1879 auto *OldVal
= CGF
.Builder
.CreateLoad(ExpectedAddr
);
1880 CGF
.Builder
.CreateStore(OldVal
, DesiredAddr
);
1882 auto OldRVal
= convertAtomicTempToRValue(ExpectedAddr
,
1883 AggValueSlot::ignored(),
1884 SourceLocation(), /*AsValue=*/false);
1885 EmitAtomicUpdateValue(CGF
, *this, OldRVal
, UpdateOp
, DesiredAddr
);
1887 EmitAtomicCompareExchangeLibcall(ExpectedAddr
.getPointer(),
1888 DesiredAddr
.getPointer(),
1890 CGF
.Builder
.CreateCondBr(Res
, ExitBB
, ContBB
);
1891 CGF
.EmitBlock(ExitBB
, /*IsFinished=*/true);
1894 void AtomicInfo::EmitAtomicUpdateOp(
1895 llvm::AtomicOrdering AO
, const llvm::function_ref
<RValue(RValue
)> &UpdateOp
,
1897 auto Failure
= llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO
);
1899 // Do the atomic load.
1900 auto *OldVal
= EmitAtomicLoadOp(Failure
, IsVolatile
);
1901 // For non-simple lvalues perform compare-and-swap procedure.
1902 auto *ContBB
= CGF
.createBasicBlock("atomic_cont");
1903 auto *ExitBB
= CGF
.createBasicBlock("atomic_exit");
1904 auto *CurBB
= CGF
.Builder
.GetInsertBlock();
1905 CGF
.EmitBlock(ContBB
);
1906 llvm::PHINode
*PHI
= CGF
.Builder
.CreatePHI(OldVal
->getType(),
1907 /*NumReservedValues=*/2);
1908 PHI
->addIncoming(OldVal
, CurBB
);
1909 Address NewAtomicAddr
= CreateTempAlloca();
1910 Address NewAtomicIntAddr
= castToAtomicIntPointer(NewAtomicAddr
);
1911 if ((LVal
.isBitField() && BFI
.Size
!= ValueSizeInBits
) ||
1912 requiresMemSetZero(getAtomicAddress().getElementType())) {
1913 CGF
.Builder
.CreateStore(PHI
, NewAtomicIntAddr
);
1915 auto OldRVal
= ConvertIntToValueOrAtomic(PHI
, AggValueSlot::ignored(),
1916 SourceLocation(), /*AsValue=*/false);
1917 EmitAtomicUpdateValue(CGF
, *this, OldRVal
, UpdateOp
, NewAtomicAddr
);
1918 auto *DesiredVal
= CGF
.Builder
.CreateLoad(NewAtomicIntAddr
);
1919 // Try to write new value using cmpxchg operation.
1920 auto Res
= EmitAtomicCompareExchangeOp(PHI
, DesiredVal
, AO
, Failure
);
1921 PHI
->addIncoming(Res
.first
, CGF
.Builder
.GetInsertBlock());
1922 CGF
.Builder
.CreateCondBr(Res
.second
, ExitBB
, ContBB
);
1923 CGF
.EmitBlock(ExitBB
, /*IsFinished=*/true);
1926 static void EmitAtomicUpdateValue(CodeGenFunction
&CGF
, AtomicInfo
&Atomics
,
1927 RValue UpdateRVal
, Address DesiredAddr
) {
1928 LValue AtomicLVal
= Atomics
.getAtomicLValue();
1930 // Build new lvalue for temp address.
1931 if (AtomicLVal
.isBitField()) {
1933 LValue::MakeBitfield(DesiredAddr
, AtomicLVal
.getBitFieldInfo(),
1934 AtomicLVal
.getType(), AtomicLVal
.getBaseInfo(),
1935 AtomicLVal
.getTBAAInfo());
1936 } else if (AtomicLVal
.isVectorElt()) {
1938 LValue::MakeVectorElt(DesiredAddr
, AtomicLVal
.getVectorIdx(),
1939 AtomicLVal
.getType(), AtomicLVal
.getBaseInfo(),
1940 AtomicLVal
.getTBAAInfo());
1942 assert(AtomicLVal
.isExtVectorElt());
1943 DesiredLVal
= LValue::MakeExtVectorElt(
1944 DesiredAddr
, AtomicLVal
.getExtVectorElts(), AtomicLVal
.getType(),
1945 AtomicLVal
.getBaseInfo(), AtomicLVal
.getTBAAInfo());
1947 // Store new value in the corresponding memory area.
1948 assert(UpdateRVal
.isScalar());
1949 CGF
.EmitStoreThroughLValue(UpdateRVal
, DesiredLVal
);
1952 void AtomicInfo::EmitAtomicUpdateLibcall(llvm::AtomicOrdering AO
,
1953 RValue UpdateRVal
, bool IsVolatile
) {
1954 auto Failure
= llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO
);
1956 Address ExpectedAddr
= CreateTempAlloca();
1958 EmitAtomicLoadLibcall(ExpectedAddr
.getPointer(), AO
, IsVolatile
);
1959 auto *ContBB
= CGF
.createBasicBlock("atomic_cont");
1960 auto *ExitBB
= CGF
.createBasicBlock("atomic_exit");
1961 CGF
.EmitBlock(ContBB
);
1962 Address DesiredAddr
= CreateTempAlloca();
1963 if ((LVal
.isBitField() && BFI
.Size
!= ValueSizeInBits
) ||
1964 requiresMemSetZero(getAtomicAddress().getElementType())) {
1965 auto *OldVal
= CGF
.Builder
.CreateLoad(ExpectedAddr
);
1966 CGF
.Builder
.CreateStore(OldVal
, DesiredAddr
);
1968 EmitAtomicUpdateValue(CGF
, *this, UpdateRVal
, DesiredAddr
);
1970 EmitAtomicCompareExchangeLibcall(ExpectedAddr
.getPointer(),
1971 DesiredAddr
.getPointer(),
1973 CGF
.Builder
.CreateCondBr(Res
, ExitBB
, ContBB
);
1974 CGF
.EmitBlock(ExitBB
, /*IsFinished=*/true);
1977 void AtomicInfo::EmitAtomicUpdateOp(llvm::AtomicOrdering AO
, RValue UpdateRVal
,
1979 auto Failure
= llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO
);
1981 // Do the atomic load.
1982 auto *OldVal
= EmitAtomicLoadOp(Failure
, IsVolatile
);
1983 // For non-simple lvalues perform compare-and-swap procedure.
1984 auto *ContBB
= CGF
.createBasicBlock("atomic_cont");
1985 auto *ExitBB
= CGF
.createBasicBlock("atomic_exit");
1986 auto *CurBB
= CGF
.Builder
.GetInsertBlock();
1987 CGF
.EmitBlock(ContBB
);
1988 llvm::PHINode
*PHI
= CGF
.Builder
.CreatePHI(OldVal
->getType(),
1989 /*NumReservedValues=*/2);
1990 PHI
->addIncoming(OldVal
, CurBB
);
1991 Address NewAtomicAddr
= CreateTempAlloca();
1992 Address NewAtomicIntAddr
= castToAtomicIntPointer(NewAtomicAddr
);
1993 if ((LVal
.isBitField() && BFI
.Size
!= ValueSizeInBits
) ||
1994 requiresMemSetZero(getAtomicAddress().getElementType())) {
1995 CGF
.Builder
.CreateStore(PHI
, NewAtomicIntAddr
);
1997 EmitAtomicUpdateValue(CGF
, *this, UpdateRVal
, NewAtomicAddr
);
1998 auto *DesiredVal
= CGF
.Builder
.CreateLoad(NewAtomicIntAddr
);
1999 // Try to write new value using cmpxchg operation.
2000 auto Res
= EmitAtomicCompareExchangeOp(PHI
, DesiredVal
, AO
, Failure
);
2001 PHI
->addIncoming(Res
.first
, CGF
.Builder
.GetInsertBlock());
2002 CGF
.Builder
.CreateCondBr(Res
.second
, ExitBB
, ContBB
);
2003 CGF
.EmitBlock(ExitBB
, /*IsFinished=*/true);
2006 void AtomicInfo::EmitAtomicUpdate(
2007 llvm::AtomicOrdering AO
, const llvm::function_ref
<RValue(RValue
)> &UpdateOp
,
2009 if (shouldUseLibcall()) {
2010 EmitAtomicUpdateLibcall(AO
, UpdateOp
, IsVolatile
);
2012 EmitAtomicUpdateOp(AO
, UpdateOp
, IsVolatile
);
2016 void AtomicInfo::EmitAtomicUpdate(llvm::AtomicOrdering AO
, RValue UpdateRVal
,
2018 if (shouldUseLibcall()) {
2019 EmitAtomicUpdateLibcall(AO
, UpdateRVal
, IsVolatile
);
2021 EmitAtomicUpdateOp(AO
, UpdateRVal
, IsVolatile
);
2025 void CodeGenFunction::EmitAtomicStore(RValue rvalue
, LValue lvalue
,
2027 bool IsVolatile
= lvalue
.isVolatileQualified();
2028 llvm::AtomicOrdering AO
;
2029 if (lvalue
.getType()->isAtomicType()) {
2030 AO
= llvm::AtomicOrdering::SequentiallyConsistent
;
2032 AO
= llvm::AtomicOrdering::Release
;
2035 return EmitAtomicStore(rvalue
, lvalue
, AO
, IsVolatile
, isInit
);
2038 /// Emit a store to an l-value of atomic type.
2040 /// Note that the r-value is expected to be an r-value *of the atomic
2041 /// type*; this means that for aggregate r-values, it should include
2042 /// storage for any padding that was necessary.
2043 void CodeGenFunction::EmitAtomicStore(RValue rvalue
, LValue dest
,
2044 llvm::AtomicOrdering AO
, bool IsVolatile
,
2046 // If this is an aggregate r-value, it should agree in type except
2047 // maybe for address-space qualification.
2048 assert(!rvalue
.isAggregate() ||
2049 rvalue
.getAggregateAddress().getElementType() ==
2050 dest
.getAddress(*this).getElementType());
2052 AtomicInfo
atomics(*this, dest
);
2053 LValue LVal
= atomics
.getAtomicLValue();
2055 // If this is an initialization, just put the value there normally.
2056 if (LVal
.isSimple()) {
2058 atomics
.emitCopyIntoMemory(rvalue
);
2062 // Check whether we should use a library call.
2063 if (atomics
.shouldUseLibcall()) {
2064 // Produce a source address.
2065 Address srcAddr
= atomics
.materializeRValue(rvalue
);
2067 // void __atomic_store(size_t size, void *mem, void *val, int order)
2069 args
.add(RValue::get(atomics
.getAtomicSizeValue()),
2070 getContext().getSizeType());
2071 args
.add(RValue::get(atomics
.getAtomicPointer()), getContext().VoidPtrTy
);
2072 args
.add(RValue::get(srcAddr
.getPointer()), getContext().VoidPtrTy
);
2074 RValue::get(llvm::ConstantInt::get(IntTy
, (int)llvm::toCABI(AO
))),
2075 getContext().IntTy
);
2076 emitAtomicLibcall(*this, "__atomic_store", getContext().VoidTy
, args
);
2080 // Okay, we're doing this natively.
2081 llvm::Value
*intValue
= atomics
.convertRValueToInt(rvalue
);
2083 // Do the atomic store.
2084 Address addr
= atomics
.castToAtomicIntPointer(atomics
.getAtomicAddress());
2085 intValue
= Builder
.CreateIntCast(
2086 intValue
, addr
.getElementType(), /*isSigned=*/false);
2087 llvm::StoreInst
*store
= Builder
.CreateStore(intValue
, addr
);
2089 if (AO
== llvm::AtomicOrdering::Acquire
)
2090 AO
= llvm::AtomicOrdering::Monotonic
;
2091 else if (AO
== llvm::AtomicOrdering::AcquireRelease
)
2092 AO
= llvm::AtomicOrdering::Release
;
2093 // Initializations don't need to be atomic.
2095 store
->setAtomic(AO
);
2097 // Other decoration.
2099 store
->setVolatile(true);
2100 CGM
.DecorateInstructionWithTBAA(store
, dest
.getTBAAInfo());
2104 // Emit simple atomic update operation.
2105 atomics
.EmitAtomicUpdate(AO
, rvalue
, IsVolatile
);
2108 /// Emit a compare-and-exchange op for atomic type.
2110 std::pair
<RValue
, llvm::Value
*> CodeGenFunction::EmitAtomicCompareExchange(
2111 LValue Obj
, RValue Expected
, RValue Desired
, SourceLocation Loc
,
2112 llvm::AtomicOrdering Success
, llvm::AtomicOrdering Failure
, bool IsWeak
,
2113 AggValueSlot Slot
) {
2114 // If this is an aggregate r-value, it should agree in type except
2115 // maybe for address-space qualification.
2116 assert(!Expected
.isAggregate() ||
2117 Expected
.getAggregateAddress().getElementType() ==
2118 Obj
.getAddress(*this).getElementType());
2119 assert(!Desired
.isAggregate() ||
2120 Desired
.getAggregateAddress().getElementType() ==
2121 Obj
.getAddress(*this).getElementType());
2122 AtomicInfo
Atomics(*this, Obj
);
2124 return Atomics
.EmitAtomicCompareExchange(Expected
, Desired
, Success
, Failure
,
2128 void CodeGenFunction::EmitAtomicUpdate(
2129 LValue LVal
, llvm::AtomicOrdering AO
,
2130 const llvm::function_ref
<RValue(RValue
)> &UpdateOp
, bool IsVolatile
) {
2131 AtomicInfo
Atomics(*this, LVal
);
2132 Atomics
.EmitAtomicUpdate(AO
, UpdateOp
, IsVolatile
);
2135 void CodeGenFunction::EmitAtomicInit(Expr
*init
, LValue dest
) {
2136 AtomicInfo
atomics(*this, dest
);
2138 switch (atomics
.getEvaluationKind()) {
2140 llvm::Value
*value
= EmitScalarExpr(init
);
2141 atomics
.emitCopyIntoMemory(RValue::get(value
));
2146 ComplexPairTy value
= EmitComplexExpr(init
);
2147 atomics
.emitCopyIntoMemory(RValue::getComplex(value
));
2151 case TEK_Aggregate
: {
2152 // Fix up the destination if the initializer isn't an expression
2154 bool Zeroed
= false;
2155 if (!init
->getType()->isAtomicType()) {
2156 Zeroed
= atomics
.emitMemSetZeroIfNecessary();
2157 dest
= atomics
.projectValue();
2160 // Evaluate the expression directly into the destination.
2161 AggValueSlot slot
= AggValueSlot::forLValue(
2162 dest
, *this, AggValueSlot::IsNotDestructed
,
2163 AggValueSlot::DoesNotNeedGCBarriers
, AggValueSlot::IsNotAliased
,
2164 AggValueSlot::DoesNotOverlap
,
2165 Zeroed
? AggValueSlot::IsZeroed
: AggValueSlot::IsNotZeroed
);
2167 EmitAggExpr(init
, slot
);
2171 llvm_unreachable("bad evaluation kind");