Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/clang/lib/CodeGen/CGAtomic.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- CGAtomic.cpp - Emit LLVM IR for atomic operations ----------------===//
2
//
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
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file contains the code for emitting atomic operations.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "CGCall.h"
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"
25
26
using namespace clang;
27
using namespace CodeGen;
28
29
namespace {
30
  class AtomicInfo {
31
    CodeGenFunction &CGF;
32
    QualType AtomicTy;
33
    QualType ValueTy;
34
    uint64_t AtomicSizeInBits;
35
    uint64_t ValueSizeInBits;
36
    CharUnits AtomicAlign;
37
    CharUnits ValueAlign;
38
    TypeEvaluationKind EvaluationKind;
39
    bool UseLibcall;
40
    LValue LVal;
41
    CGBitFieldInfo BFI;
42
  public:
43
    AtomicInfo(CodeGenFunction &CGF, LValue &lvalue)
44
        : CGF(CGF), AtomicSizeInBits(0), ValueSizeInBits(0),
45
0
          EvaluationKind(TEK_Scalar), UseLibcall(true) {
46
0
      assert(!lvalue.isGlobalReg());
47
0
      ASTContext &C = CGF.getContext();
48
0
      if (lvalue.isSimple()) {
49
0
        AtomicTy = lvalue.getType();
50
0
        if (auto *ATy = AtomicTy->getAs<AtomicType>())
51
0
          ValueTy = ATy->getValueType();
52
0
        else
53
0
          ValueTy = AtomicTy;
54
0
        EvaluationKind = CGF.getEvaluationKind(ValueTy);
55
56
0
        uint64_t ValueAlignInBits;
57
0
        uint64_t AtomicAlignInBits;
58
0
        TypeInfo ValueTI = C.getTypeInfo(ValueTy);
59
0
        ValueSizeInBits = ValueTI.Width;
60
0
        ValueAlignInBits = ValueTI.Align;
61
62
0
        TypeInfo AtomicTI = C.getTypeInfo(AtomicTy);
63
0
        AtomicSizeInBits = AtomicTI.Width;
64
0
        AtomicAlignInBits = AtomicTI.Align;
65
66
0
        assert(ValueSizeInBits <= AtomicSizeInBits);
67
0
        assert(ValueAlignInBits <= AtomicAlignInBits);
68
69
0
        AtomicAlign = C.toCharUnitsFromBits(AtomicAlignInBits);
70
0
        ValueAlign = C.toCharUnitsFromBits(ValueAlignInBits);
71
0
        if (lvalue.getAlignment().isZero())
72
0
          lvalue.setAlignment(AtomicAlign);
73
74
0
        LVal = lvalue;
75
0
      } else if (lvalue.isBitField()) {
76
0
        ValueTy = lvalue.getType();
77
0
        ValueSizeInBits = C.getTypeSize(ValueTy);
78
0
        auto &OrigBFI = lvalue.getBitFieldInfo();
79
0
        auto Offset = OrigBFI.Offset % C.toBits(lvalue.getAlignment());
80
0
        AtomicSizeInBits = C.toBits(
81
0
            C.toCharUnitsFromBits(Offset + OrigBFI.Size + C.getCharWidth() - 1)
82
0
                .alignTo(lvalue.getAlignment()));
83
0
        llvm::Value *BitFieldPtr = lvalue.getBitFieldPointer();
84
0
        auto OffsetInChars =
85
0
            (C.toCharUnitsFromBits(OrigBFI.Offset) / lvalue.getAlignment()) *
86
0
            lvalue.getAlignment();
87
0
        llvm::Value *StoragePtr = CGF.Builder.CreateConstGEP1_64(
88
0
            CGF.Int8Ty, BitFieldPtr, OffsetInChars.getQuantity());
89
0
        StoragePtr = CGF.Builder.CreateAddrSpaceCast(
90
0
            StoragePtr, CGF.UnqualPtrTy, "atomic_bitfield_base");
91
0
        BFI = OrigBFI;
92
0
        BFI.Offset = Offset;
93
0
        BFI.StorageSize = AtomicSizeInBits;
94
0
        BFI.StorageOffset += OffsetInChars;
95
0
        llvm::Type *StorageTy = CGF.Builder.getIntNTy(AtomicSizeInBits);
96
0
        LVal = LValue::MakeBitfield(
97
0
            Address(StoragePtr, StorageTy, lvalue.getAlignment()), BFI,
98
0
            lvalue.getType(), lvalue.getBaseInfo(), lvalue.getTBAAInfo());
99
0
        AtomicTy = C.getIntTypeForBitwidth(AtomicSizeInBits, OrigBFI.IsSigned);
100
0
        if (AtomicTy.isNull()) {
101
0
          llvm::APInt Size(
102
0
              /*numBits=*/32,
103
0
              C.toCharUnitsFromBits(AtomicSizeInBits).getQuantity());
104
0
          AtomicTy = C.getConstantArrayType(C.CharTy, Size, nullptr,
105
0
                                            ArraySizeModifier::Normal,
106
0
                                            /*IndexTypeQuals=*/0);
107
0
        }
108
0
        AtomicAlign = ValueAlign = lvalue.getAlignment();
109
0
      } else if (lvalue.isVectorElt()) {
110
0
        ValueTy = lvalue.getType()->castAs<VectorType>()->getElementType();
111
0
        ValueSizeInBits = C.getTypeSize(ValueTy);
112
0
        AtomicTy = lvalue.getType();
113
0
        AtomicSizeInBits = C.getTypeSize(AtomicTy);
114
0
        AtomicAlign = ValueAlign = lvalue.getAlignment();
115
0
        LVal = lvalue;
116
0
      } else {
117
0
        assert(lvalue.isExtVectorElt());
118
0
        ValueTy = lvalue.getType();
119
0
        ValueSizeInBits = C.getTypeSize(ValueTy);
120
0
        AtomicTy = ValueTy = CGF.getContext().getExtVectorType(
121
0
            lvalue.getType(), cast<llvm::FixedVectorType>(
122
0
                                  lvalue.getExtVectorAddress().getElementType())
123
0
                                  ->getNumElements());
124
0
        AtomicSizeInBits = C.getTypeSize(AtomicTy);
125
0
        AtomicAlign = ValueAlign = lvalue.getAlignment();
126
0
        LVal = lvalue;
127
0
      }
128
0
      UseLibcall = !C.getTargetInfo().hasBuiltinAtomic(
129
0
          AtomicSizeInBits, C.toBits(lvalue.getAlignment()));
130
0
    }
131
132
0
    QualType getAtomicType() const { return AtomicTy; }
133
0
    QualType getValueType() const { return ValueTy; }
134
0
    CharUnits getAtomicAlignment() const { return AtomicAlign; }
135
0
    uint64_t getAtomicSizeInBits() const { return AtomicSizeInBits; }
136
0
    uint64_t getValueSizeInBits() const { return ValueSizeInBits; }
137
0
    TypeEvaluationKind getEvaluationKind() const { return EvaluationKind; }
138
0
    bool shouldUseLibcall() const { return UseLibcall; }
139
0
    const LValue &getAtomicLValue() const { return LVal; }
140
0
    llvm::Value *getAtomicPointer() const {
141
0
      if (LVal.isSimple())
142
0
        return LVal.getPointer(CGF);
143
0
      else if (LVal.isBitField())
144
0
        return LVal.getBitFieldPointer();
145
0
      else if (LVal.isVectorElt())
146
0
        return LVal.getVectorPointer();
147
0
      assert(LVal.isExtVectorElt());
148
0
      return LVal.getExtVectorPointer();
149
0
    }
150
0
    Address getAtomicAddress() const {
151
0
      llvm::Type *ElTy;
152
0
      if (LVal.isSimple())
153
0
        ElTy = LVal.getAddress(CGF).getElementType();
154
0
      else if (LVal.isBitField())
155
0
        ElTy = LVal.getBitFieldAddress().getElementType();
156
0
      else if (LVal.isVectorElt())
157
0
        ElTy = LVal.getVectorAddress().getElementType();
158
0
      else
159
0
        ElTy = LVal.getExtVectorAddress().getElementType();
160
0
      return Address(getAtomicPointer(), ElTy, getAtomicAlignment());
161
0
    }
162
163
0
    Address getAtomicAddressAsAtomicIntPointer() const {
164
0
      return castToAtomicIntPointer(getAtomicAddress());
165
0
    }
166
167
    /// Is the atomic size larger than the underlying value type?
168
    ///
169
    /// Note that the absence of padding does not mean that atomic
170
    /// objects are completely interchangeable with non-atomic
171
    /// objects: we might have promoted the alignment of a type
172
    /// without making it bigger.
173
0
    bool hasPadding() const {
174
0
      return (ValueSizeInBits != AtomicSizeInBits);
175
0
    }
176
177
    bool emitMemSetZeroIfNecessary() const;
178
179
0
    llvm::Value *getAtomicSizeValue() const {
180
0
      CharUnits size = CGF.getContext().toCharUnitsFromBits(AtomicSizeInBits);
181
0
      return CGF.CGM.getSize(size);
182
0
    }
183
184
    /// Cast the given pointer to an integer pointer suitable for atomic
185
    /// operations if the source.
186
    Address castToAtomicIntPointer(Address Addr) const;
187
188
    /// If Addr is compatible with the iN that will be used for an atomic
189
    /// operation, bitcast it. Otherwise, create a temporary that is suitable
190
    /// and copy the value across.
191
    Address convertToAtomicIntPointer(Address Addr) const;
192
193
    /// Turn an atomic-layout object into an r-value.
194
    RValue convertAtomicTempToRValue(Address addr, AggValueSlot resultSlot,
195
                                     SourceLocation loc, bool AsValue) const;
196
197
    /// Converts a rvalue to integer value.
198
    llvm::Value *convertRValueToInt(RValue RVal) const;
199
200
    RValue ConvertIntToValueOrAtomic(llvm::Value *IntVal,
201
                                     AggValueSlot ResultSlot,
202
                                     SourceLocation Loc, bool AsValue) const;
203
204
    /// Copy an atomic r-value into atomic-layout memory.
205
    void emitCopyIntoMemory(RValue rvalue) const;
206
207
    /// Project an l-value down to the value field.
208
0
    LValue projectValue() const {
209
0
      assert(LVal.isSimple());
210
0
      Address addr = getAtomicAddress();
211
0
      if (hasPadding())
212
0
        addr = CGF.Builder.CreateStructGEP(addr, 0);
213
214
0
      return LValue::MakeAddr(addr, getValueType(), CGF.getContext(),
215
0
                              LVal.getBaseInfo(), LVal.getTBAAInfo());
216
0
    }
217
218
    /// Emits atomic load.
219
    /// \returns Loaded value.
220
    RValue EmitAtomicLoad(AggValueSlot ResultSlot, SourceLocation Loc,
221
                          bool AsValue, llvm::AtomicOrdering AO,
222
                          bool IsVolatile);
223
224
    /// Emits atomic compare-and-exchange sequence.
225
    /// \param Expected Expected value.
226
    /// \param Desired Desired value.
227
    /// \param Success Atomic ordering for success operation.
228
    /// \param Failure Atomic ordering for failed operation.
229
    /// \param IsWeak true if atomic operation is weak, false otherwise.
230
    /// \returns Pair of values: previous value from storage (value type) and
231
    /// boolean flag (i1 type) with true if success and false otherwise.
232
    std::pair<RValue, llvm::Value *>
233
    EmitAtomicCompareExchange(RValue Expected, RValue Desired,
234
                              llvm::AtomicOrdering Success =
235
                                  llvm::AtomicOrdering::SequentiallyConsistent,
236
                              llvm::AtomicOrdering Failure =
237
                                  llvm::AtomicOrdering::SequentiallyConsistent,
238
                              bool IsWeak = false);
239
240
    /// Emits atomic update.
241
    /// \param AO Atomic ordering.
242
    /// \param UpdateOp Update operation for the current lvalue.
243
    void EmitAtomicUpdate(llvm::AtomicOrdering AO,
244
                          const llvm::function_ref<RValue(RValue)> &UpdateOp,
245
                          bool IsVolatile);
246
    /// Emits atomic update.
247
    /// \param AO Atomic ordering.
248
    void EmitAtomicUpdate(llvm::AtomicOrdering AO, RValue UpdateRVal,
249
                          bool IsVolatile);
250
251
    /// Materialize an atomic r-value in atomic-layout memory.
252
    Address materializeRValue(RValue rvalue) const;
253
254
    /// Creates temp alloca for intermediate operations on atomic value.
255
    Address CreateTempAlloca() const;
256
  private:
257
    bool requiresMemSetZero(llvm::Type *type) const;
258
259
260
    /// Emits atomic load as a libcall.
261
    void EmitAtomicLoadLibcall(llvm::Value *AddForLoaded,
262
                               llvm::AtomicOrdering AO, bool IsVolatile);
263
    /// Emits atomic load as LLVM instruction.
264
    llvm::Value *EmitAtomicLoadOp(llvm::AtomicOrdering AO, bool IsVolatile);
265
    /// Emits atomic compare-and-exchange op as a libcall.
266
    llvm::Value *EmitAtomicCompareExchangeLibcall(
267
        llvm::Value *ExpectedAddr, llvm::Value *DesiredAddr,
268
        llvm::AtomicOrdering Success =
269
            llvm::AtomicOrdering::SequentiallyConsistent,
270
        llvm::AtomicOrdering Failure =
271
            llvm::AtomicOrdering::SequentiallyConsistent);
272
    /// Emits atomic compare-and-exchange op as LLVM instruction.
273
    std::pair<llvm::Value *, llvm::Value *> EmitAtomicCompareExchangeOp(
274
        llvm::Value *ExpectedVal, llvm::Value *DesiredVal,
275
        llvm::AtomicOrdering Success =
276
            llvm::AtomicOrdering::SequentiallyConsistent,
277
        llvm::AtomicOrdering Failure =
278
            llvm::AtomicOrdering::SequentiallyConsistent,
279
        bool IsWeak = false);
280
    /// Emit atomic update as libcalls.
281
    void
282
    EmitAtomicUpdateLibcall(llvm::AtomicOrdering AO,
283
                            const llvm::function_ref<RValue(RValue)> &UpdateOp,
284
                            bool IsVolatile);
285
    /// Emit atomic update as LLVM instructions.
286
    void EmitAtomicUpdateOp(llvm::AtomicOrdering AO,
287
                            const llvm::function_ref<RValue(RValue)> &UpdateOp,
288
                            bool IsVolatile);
289
    /// Emit atomic update as libcalls.
290
    void EmitAtomicUpdateLibcall(llvm::AtomicOrdering AO, RValue UpdateRVal,
291
                                 bool IsVolatile);
292
    /// Emit atomic update as LLVM instructions.
293
    void EmitAtomicUpdateOp(llvm::AtomicOrdering AO, RValue UpdateRal,
294
                            bool IsVolatile);
295
  };
296
}
297
298
0
Address AtomicInfo::CreateTempAlloca() const {
299
0
  Address TempAlloca = CGF.CreateMemTemp(
300
0
      (LVal.isBitField() && ValueSizeInBits > AtomicSizeInBits) ? ValueTy
301
0
                                                                : AtomicTy,
302
0
      getAtomicAlignment(),
303
0
      "atomic-temp");
304
  // Cast to pointer to value type for bitfields.
305
0
  if (LVal.isBitField())
306
0
    return CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
307
0
        TempAlloca, getAtomicAddress().getType(),
308
0
        getAtomicAddress().getElementType());
309
0
  return TempAlloca;
310
0
}
311
312
static RValue emitAtomicLibcall(CodeGenFunction &CGF,
313
                                StringRef fnName,
314
                                QualType resultType,
315
0
                                CallArgList &args) {
316
0
  const CGFunctionInfo &fnInfo =
317
0
    CGF.CGM.getTypes().arrangeBuiltinFunctionCall(resultType, args);
318
0
  llvm::FunctionType *fnTy = CGF.CGM.getTypes().GetFunctionType(fnInfo);
319
0
  llvm::AttrBuilder fnAttrB(CGF.getLLVMContext());
320
0
  fnAttrB.addAttribute(llvm::Attribute::NoUnwind);
321
0
  fnAttrB.addAttribute(llvm::Attribute::WillReturn);
322
0
  llvm::AttributeList fnAttrs = llvm::AttributeList::get(
323
0
      CGF.getLLVMContext(), llvm::AttributeList::FunctionIndex, fnAttrB);
324
325
0
  llvm::FunctionCallee fn =
326
0
      CGF.CGM.CreateRuntimeFunction(fnTy, fnName, fnAttrs);
327
0
  auto callee = CGCallee::forDirect(fn);
328
0
  return CGF.EmitCall(fnInfo, callee, ReturnValueSlot(), args);
329
0
}
330
331
/// Does a store of the given IR type modify the full expected width?
332
static bool isFullSizeType(CodeGenModule &CGM, llvm::Type *type,
333
0
                           uint64_t expectedSize) {
334
0
  return (CGM.getDataLayout().getTypeStoreSize(type) * 8 == expectedSize);
335
0
}
336
337
/// Does the atomic type require memsetting to zero before initialization?
338
///
339
/// The IR type is provided as a way of making certain queries faster.
340
0
bool AtomicInfo::requiresMemSetZero(llvm::Type *type) const {
341
  // If the atomic type has size padding, we definitely need a memset.
342
0
  if (hasPadding()) return true;
343
344
  // Otherwise, do some simple heuristics to try to avoid it:
345
0
  switch (getEvaluationKind()) {
346
  // For scalars and complexes, check whether the store size of the
347
  // type uses the full size.
348
0
  case TEK_Scalar:
349
0
    return !isFullSizeType(CGF.CGM, type, AtomicSizeInBits);
350
0
  case TEK_Complex:
351
0
    return !isFullSizeType(CGF.CGM, type->getStructElementType(0),
352
0
                           AtomicSizeInBits / 2);
353
354
  // Padding in structs has an undefined bit pattern.  User beware.
355
0
  case TEK_Aggregate:
356
0
    return false;
357
0
  }
358
0
  llvm_unreachable("bad evaluation kind");
359
0
}
360
361
0
bool AtomicInfo::emitMemSetZeroIfNecessary() const {
362
0
  assert(LVal.isSimple());
363
0
  Address addr = LVal.getAddress(CGF);
364
0
  if (!requiresMemSetZero(addr.getElementType()))
365
0
    return false;
366
367
0
  CGF.Builder.CreateMemSet(
368
0
      addr.getPointer(), llvm::ConstantInt::get(CGF.Int8Ty, 0),
369
0
      CGF.getContext().toCharUnitsFromBits(AtomicSizeInBits).getQuantity(),
370
0
      LVal.getAlignment().getAsAlign());
371
0
  return true;
372
0
}
373
374
static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak,
375
                              Address Dest, Address Ptr,
376
                              Address Val1, Address Val2,
377
                              uint64_t Size,
378
                              llvm::AtomicOrdering SuccessOrder,
379
                              llvm::AtomicOrdering FailureOrder,
380
0
                              llvm::SyncScope::ID Scope) {
381
  // Note that cmpxchg doesn't support weak cmpxchg, at least at the moment.
382
0
  llvm::Value *Expected = CGF.Builder.CreateLoad(Val1);
383
0
  llvm::Value *Desired = CGF.Builder.CreateLoad(Val2);
384
385
0
  llvm::AtomicCmpXchgInst *Pair = CGF.Builder.CreateAtomicCmpXchg(
386
0
      Ptr, Expected, Desired, SuccessOrder, FailureOrder, Scope);
387
0
  Pair->setVolatile(E->isVolatile());
388
0
  Pair->setWeak(IsWeak);
389
390
  // Cmp holds the result of the compare-exchange operation: true on success,
391
  // false on failure.
392
0
  llvm::Value *Old = CGF.Builder.CreateExtractValue(Pair, 0);
393
0
  llvm::Value *Cmp = CGF.Builder.CreateExtractValue(Pair, 1);
394
395
  // This basic block is used to hold the store instruction if the operation
396
  // failed.
397
0
  llvm::BasicBlock *StoreExpectedBB =
398
0
      CGF.createBasicBlock("cmpxchg.store_expected", CGF.CurFn);
399
400
  // This basic block is the exit point of the operation, we should end up
401
  // here regardless of whether or not the operation succeeded.
402
0
  llvm::BasicBlock *ContinueBB =
403
0
      CGF.createBasicBlock("cmpxchg.continue", CGF.CurFn);
404
405
  // Update Expected if Expected isn't equal to Old, otherwise branch to the
406
  // exit point.
407
0
  CGF.Builder.CreateCondBr(Cmp, ContinueBB, StoreExpectedBB);
408
409
0
  CGF.Builder.SetInsertPoint(StoreExpectedBB);
410
  // Update the memory at Expected with Old's value.
411
0
  CGF.Builder.CreateStore(Old, Val1);
412
  // Finally, branch to the exit point.
413
0
  CGF.Builder.CreateBr(ContinueBB);
414
415
0
  CGF.Builder.SetInsertPoint(ContinueBB);
416
  // Update the memory at Dest with Cmp's value.
417
0
  CGF.EmitStoreOfScalar(Cmp, CGF.MakeAddrLValue(Dest, E->getType()));
418
0
}
419
420
/// Given an ordering required on success, emit all possible cmpxchg
421
/// instructions to cope with the provided (but possibly only dynamically known)
422
/// FailureOrder.
423
static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E,
424
                                        bool IsWeak, Address Dest, Address Ptr,
425
                                        Address Val1, Address Val2,
426
                                        llvm::Value *FailureOrderVal,
427
                                        uint64_t Size,
428
                                        llvm::AtomicOrdering SuccessOrder,
429
0
                                        llvm::SyncScope::ID Scope) {
430
0
  llvm::AtomicOrdering FailureOrder;
431
0
  if (llvm::ConstantInt *FO = dyn_cast<llvm::ConstantInt>(FailureOrderVal)) {
432
0
    auto FOS = FO->getSExtValue();
433
0
    if (!llvm::isValidAtomicOrderingCABI(FOS))
434
0
      FailureOrder = llvm::AtomicOrdering::Monotonic;
435
0
    else
436
0
      switch ((llvm::AtomicOrderingCABI)FOS) {
437
0
      case llvm::AtomicOrderingCABI::relaxed:
438
      // 31.7.2.18: "The failure argument shall not be memory_order_release
439
      // nor memory_order_acq_rel". Fallback to monotonic.
440
0
      case llvm::AtomicOrderingCABI::release:
441
0
      case llvm::AtomicOrderingCABI::acq_rel:
442
0
        FailureOrder = llvm::AtomicOrdering::Monotonic;
443
0
        break;
444
0
      case llvm::AtomicOrderingCABI::consume:
445
0
      case llvm::AtomicOrderingCABI::acquire:
446
0
        FailureOrder = llvm::AtomicOrdering::Acquire;
447
0
        break;
448
0
      case llvm::AtomicOrderingCABI::seq_cst:
449
0
        FailureOrder = llvm::AtomicOrdering::SequentiallyConsistent;
450
0
        break;
451
0
      }
452
    // Prior to c++17, "the failure argument shall be no stronger than the
453
    // success argument". This condition has been lifted and the only
454
    // precondition is 31.7.2.18. Effectively treat this as a DR and skip
455
    // language version checks.
456
0
    emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
457
0
                      FailureOrder, Scope);
458
0
    return;
459
0
  }
460
461
  // Create all the relevant BB's
462
0
  auto *MonotonicBB = CGF.createBasicBlock("monotonic_fail", CGF.CurFn);
463
0
  auto *AcquireBB = CGF.createBasicBlock("acquire_fail", CGF.CurFn);
464
0
  auto *SeqCstBB = CGF.createBasicBlock("seqcst_fail", CGF.CurFn);
465
0
  auto *ContBB = CGF.createBasicBlock("atomic.continue", CGF.CurFn);
466
467
  // MonotonicBB is arbitrarily chosen as the default case; in practice, this
468
  // doesn't matter unless someone is crazy enough to use something that
469
  // doesn't fold to a constant for the ordering.
470
0
  llvm::SwitchInst *SI = CGF.Builder.CreateSwitch(FailureOrderVal, MonotonicBB);
471
  // Implemented as acquire, since it's the closest in LLVM.
472
0
  SI->addCase(CGF.Builder.getInt32((int)llvm::AtomicOrderingCABI::consume),
473
0
              AcquireBB);
474
0
  SI->addCase(CGF.Builder.getInt32((int)llvm::AtomicOrderingCABI::acquire),
475
0
              AcquireBB);
476
0
  SI->addCase(CGF.Builder.getInt32((int)llvm::AtomicOrderingCABI::seq_cst),
477
0
              SeqCstBB);
478
479
  // Emit all the different atomics
480
0
  CGF.Builder.SetInsertPoint(MonotonicBB);
481
0
  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
482
0
                    Size, SuccessOrder, llvm::AtomicOrdering::Monotonic, Scope);
483
0
  CGF.Builder.CreateBr(ContBB);
484
485
0
  CGF.Builder.SetInsertPoint(AcquireBB);
486
0
  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
487
0
                    llvm::AtomicOrdering::Acquire, Scope);
488
0
  CGF.Builder.CreateBr(ContBB);
489
490
0
  CGF.Builder.SetInsertPoint(SeqCstBB);
491
0
  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
492
0
                    llvm::AtomicOrdering::SequentiallyConsistent, Scope);
493
0
  CGF.Builder.CreateBr(ContBB);
494
495
0
  CGF.Builder.SetInsertPoint(ContBB);
496
0
}
497
498
/// Duplicate the atomic min/max operation in conventional IR for the builtin
499
/// variants that return the new rather than the original value.
500
static llvm::Value *EmitPostAtomicMinMax(CGBuilderTy &Builder,
501
                                         AtomicExpr::AtomicOp Op,
502
                                         bool IsSigned,
503
                                         llvm::Value *OldVal,
504
0
                                         llvm::Value *RHS) {
505
0
  llvm::CmpInst::Predicate Pred;
506
0
  switch (Op) {
507
0
  default:
508
0
    llvm_unreachable("Unexpected min/max operation");
509
0
  case AtomicExpr::AO__atomic_max_fetch:
510
0
  case AtomicExpr::AO__scoped_atomic_max_fetch:
511
0
    Pred = IsSigned ? llvm::CmpInst::ICMP_SGT : llvm::CmpInst::ICMP_UGT;
512
0
    break;
513
0
  case AtomicExpr::AO__atomic_min_fetch:
514
0
  case AtomicExpr::AO__scoped_atomic_min_fetch:
515
0
    Pred = IsSigned ? llvm::CmpInst::ICMP_SLT : llvm::CmpInst::ICMP_ULT;
516
0
    break;
517
0
  }
518
0
  llvm::Value *Cmp = Builder.CreateICmp(Pred, OldVal, RHS, "tst");
519
0
  return Builder.CreateSelect(Cmp, OldVal, RHS, "newval");
520
0
}
521
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
0
                         llvm::SyncScope::ID Scope) {
527
0
  llvm::AtomicRMWInst::BinOp Op = llvm::AtomicRMWInst::Add;
528
0
  bool PostOpMinMax = false;
529
0
  unsigned PostOp = 0;
530
531
0
  switch (E->getOp()) {
532
0
  case AtomicExpr::AO__c11_atomic_init:
533
0
  case AtomicExpr::AO__opencl_atomic_init:
534
0
    llvm_unreachable("Already handled!");
535
536
0
  case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
537
0
  case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
538
0
  case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
539
0
    emitAtomicCmpXchgFailureSet(CGF, E, false, Dest, Ptr, Val1, Val2,
540
0
                                FailureOrder, Size, Order, Scope);
541
0
    return;
542
0
  case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
543
0
  case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
544
0
  case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
545
0
    emitAtomicCmpXchgFailureSet(CGF, E, true, Dest, Ptr, Val1, Val2,
546
0
                                FailureOrder, Size, Order, Scope);
547
0
    return;
548
0
  case AtomicExpr::AO__atomic_compare_exchange:
549
0
  case AtomicExpr::AO__atomic_compare_exchange_n:
550
0
  case AtomicExpr::AO__scoped_atomic_compare_exchange:
551
0
  case AtomicExpr::AO__scoped_atomic_compare_exchange_n: {
552
0
    if (llvm::ConstantInt *IsWeakC = dyn_cast<llvm::ConstantInt>(IsWeak)) {
553
0
      emitAtomicCmpXchgFailureSet(CGF, E, IsWeakC->getZExtValue(), Dest, Ptr,
554
0
                                  Val1, Val2, FailureOrder, Size, Order, Scope);
555
0
    } else {
556
      // Create all the relevant BB's
557
0
      llvm::BasicBlock *StrongBB =
558
0
          CGF.createBasicBlock("cmpxchg.strong", CGF.CurFn);
559
0
      llvm::BasicBlock *WeakBB = CGF.createBasicBlock("cmxchg.weak", CGF.CurFn);
560
0
      llvm::BasicBlock *ContBB =
561
0
          CGF.createBasicBlock("cmpxchg.continue", CGF.CurFn);
562
563
0
      llvm::SwitchInst *SI = CGF.Builder.CreateSwitch(IsWeak, WeakBB);
564
0
      SI->addCase(CGF.Builder.getInt1(false), StrongBB);
565
566
0
      CGF.Builder.SetInsertPoint(StrongBB);
567
0
      emitAtomicCmpXchgFailureSet(CGF, E, false, Dest, Ptr, Val1, Val2,
568
0
                                  FailureOrder, Size, Order, Scope);
569
0
      CGF.Builder.CreateBr(ContBB);
570
571
0
      CGF.Builder.SetInsertPoint(WeakBB);
572
0
      emitAtomicCmpXchgFailureSet(CGF, E, true, Dest, Ptr, Val1, Val2,
573
0
                                  FailureOrder, Size, Order, Scope);
574
0
      CGF.Builder.CreateBr(ContBB);
575
576
0
      CGF.Builder.SetInsertPoint(ContBB);
577
0
    }
578
0
    return;
579
0
  }
580
0
  case AtomicExpr::AO__c11_atomic_load:
581
0
  case AtomicExpr::AO__opencl_atomic_load:
582
0
  case AtomicExpr::AO__hip_atomic_load:
583
0
  case AtomicExpr::AO__atomic_load_n:
584
0
  case AtomicExpr::AO__atomic_load:
585
0
  case AtomicExpr::AO__scoped_atomic_load_n:
586
0
  case AtomicExpr::AO__scoped_atomic_load: {
587
0
    llvm::LoadInst *Load = CGF.Builder.CreateLoad(Ptr);
588
0
    Load->setAtomic(Order, Scope);
589
0
    Load->setVolatile(E->isVolatile());
590
0
    CGF.Builder.CreateStore(Load, Dest);
591
0
    return;
592
0
  }
593
594
0
  case AtomicExpr::AO__c11_atomic_store:
595
0
  case AtomicExpr::AO__opencl_atomic_store:
596
0
  case AtomicExpr::AO__hip_atomic_store:
597
0
  case AtomicExpr::AO__atomic_store:
598
0
  case AtomicExpr::AO__atomic_store_n:
599
0
  case AtomicExpr::AO__scoped_atomic_store:
600
0
  case AtomicExpr::AO__scoped_atomic_store_n: {
601
0
    llvm::Value *LoadVal1 = CGF.Builder.CreateLoad(Val1);
602
0
    llvm::StoreInst *Store = CGF.Builder.CreateStore(LoadVal1, Ptr);
603
0
    Store->setAtomic(Order, Scope);
604
0
    Store->setVolatile(E->isVolatile());
605
0
    return;
606
0
  }
607
608
0
  case AtomicExpr::AO__c11_atomic_exchange:
609
0
  case AtomicExpr::AO__hip_atomic_exchange:
610
0
  case AtomicExpr::AO__opencl_atomic_exchange:
611
0
  case AtomicExpr::AO__atomic_exchange_n:
612
0
  case AtomicExpr::AO__atomic_exchange:
613
0
  case AtomicExpr::AO__scoped_atomic_exchange_n:
614
0
  case AtomicExpr::AO__scoped_atomic_exchange:
615
0
    Op = llvm::AtomicRMWInst::Xchg;
616
0
    break;
617
618
0
  case AtomicExpr::AO__atomic_add_fetch:
619
0
  case AtomicExpr::AO__scoped_atomic_add_fetch:
620
0
    PostOp = E->getValueType()->isFloatingType() ? llvm::Instruction::FAdd
621
0
                                                 : llvm::Instruction::Add;
622
0
    [[fallthrough]];
623
0
  case AtomicExpr::AO__c11_atomic_fetch_add:
624
0
  case AtomicExpr::AO__hip_atomic_fetch_add:
625
0
  case AtomicExpr::AO__opencl_atomic_fetch_add:
626
0
  case AtomicExpr::AO__atomic_fetch_add:
627
0
  case AtomicExpr::AO__scoped_atomic_fetch_add:
628
0
    Op = E->getValueType()->isFloatingType() ? llvm::AtomicRMWInst::FAdd
629
0
                                             : llvm::AtomicRMWInst::Add;
630
0
    break;
631
632
0
  case AtomicExpr::AO__atomic_sub_fetch:
633
0
  case AtomicExpr::AO__scoped_atomic_sub_fetch:
634
0
    PostOp = E->getValueType()->isFloatingType() ? llvm::Instruction::FSub
635
0
                                                 : llvm::Instruction::Sub;
636
0
    [[fallthrough]];
637
0
  case AtomicExpr::AO__c11_atomic_fetch_sub:
638
0
  case AtomicExpr::AO__hip_atomic_fetch_sub:
639
0
  case AtomicExpr::AO__opencl_atomic_fetch_sub:
640
0
  case AtomicExpr::AO__atomic_fetch_sub:
641
0
  case AtomicExpr::AO__scoped_atomic_fetch_sub:
642
0
    Op = E->getValueType()->isFloatingType() ? llvm::AtomicRMWInst::FSub
643
0
                                             : llvm::AtomicRMWInst::Sub;
644
0
    break;
645
646
0
  case AtomicExpr::AO__atomic_min_fetch:
647
0
  case AtomicExpr::AO__scoped_atomic_min_fetch:
648
0
    PostOpMinMax = true;
649
0
    [[fallthrough]];
650
0
  case AtomicExpr::AO__c11_atomic_fetch_min:
651
0
  case AtomicExpr::AO__hip_atomic_fetch_min:
652
0
  case AtomicExpr::AO__opencl_atomic_fetch_min:
653
0
  case AtomicExpr::AO__atomic_fetch_min:
654
0
  case AtomicExpr::AO__scoped_atomic_fetch_min:
655
0
    Op = E->getValueType()->isFloatingType()
656
0
             ? llvm::AtomicRMWInst::FMin
657
0
             : (E->getValueType()->isSignedIntegerType()
658
0
                    ? llvm::AtomicRMWInst::Min
659
0
                    : llvm::AtomicRMWInst::UMin);
660
0
    break;
661
662
0
  case AtomicExpr::AO__atomic_max_fetch:
663
0
  case AtomicExpr::AO__scoped_atomic_max_fetch:
664
0
    PostOpMinMax = true;
665
0
    [[fallthrough]];
666
0
  case AtomicExpr::AO__c11_atomic_fetch_max:
667
0
  case AtomicExpr::AO__hip_atomic_fetch_max:
668
0
  case AtomicExpr::AO__opencl_atomic_fetch_max:
669
0
  case AtomicExpr::AO__atomic_fetch_max:
670
0
  case AtomicExpr::AO__scoped_atomic_fetch_max:
671
0
    Op = E->getValueType()->isFloatingType()
672
0
             ? llvm::AtomicRMWInst::FMax
673
0
             : (E->getValueType()->isSignedIntegerType()
674
0
                    ? llvm::AtomicRMWInst::Max
675
0
                    : llvm::AtomicRMWInst::UMax);
676
0
    break;
677
678
0
  case AtomicExpr::AO__atomic_and_fetch:
679
0
  case AtomicExpr::AO__scoped_atomic_and_fetch:
680
0
    PostOp = llvm::Instruction::And;
681
0
    [[fallthrough]];
682
0
  case AtomicExpr::AO__c11_atomic_fetch_and:
683
0
  case AtomicExpr::AO__hip_atomic_fetch_and:
684
0
  case AtomicExpr::AO__opencl_atomic_fetch_and:
685
0
  case AtomicExpr::AO__atomic_fetch_and:
686
0
  case AtomicExpr::AO__scoped_atomic_fetch_and:
687
0
    Op = llvm::AtomicRMWInst::And;
688
0
    break;
689
690
0
  case AtomicExpr::AO__atomic_or_fetch:
691
0
  case AtomicExpr::AO__scoped_atomic_or_fetch:
692
0
    PostOp = llvm::Instruction::Or;
693
0
    [[fallthrough]];
694
0
  case AtomicExpr::AO__c11_atomic_fetch_or:
695
0
  case AtomicExpr::AO__hip_atomic_fetch_or:
696
0
  case AtomicExpr::AO__opencl_atomic_fetch_or:
697
0
  case AtomicExpr::AO__atomic_fetch_or:
698
0
  case AtomicExpr::AO__scoped_atomic_fetch_or:
699
0
    Op = llvm::AtomicRMWInst::Or;
700
0
    break;
701
702
0
  case AtomicExpr::AO__atomic_xor_fetch:
703
0
  case AtomicExpr::AO__scoped_atomic_xor_fetch:
704
0
    PostOp = llvm::Instruction::Xor;
705
0
    [[fallthrough]];
706
0
  case AtomicExpr::AO__c11_atomic_fetch_xor:
707
0
  case AtomicExpr::AO__hip_atomic_fetch_xor:
708
0
  case AtomicExpr::AO__opencl_atomic_fetch_xor:
709
0
  case AtomicExpr::AO__atomic_fetch_xor:
710
0
  case AtomicExpr::AO__scoped_atomic_fetch_xor:
711
0
    Op = llvm::AtomicRMWInst::Xor;
712
0
    break;
713
714
0
  case AtomicExpr::AO__atomic_nand_fetch:
715
0
  case AtomicExpr::AO__scoped_atomic_nand_fetch:
716
0
    PostOp = llvm::Instruction::And; // the NOT is special cased below
717
0
    [[fallthrough]];
718
0
  case AtomicExpr::AO__c11_atomic_fetch_nand:
719
0
  case AtomicExpr::AO__atomic_fetch_nand:
720
0
  case AtomicExpr::AO__scoped_atomic_fetch_nand:
721
0
    Op = llvm::AtomicRMWInst::Nand;
722
0
    break;
723
0
  }
724
725
0
  llvm::Value *LoadVal1 = CGF.Builder.CreateLoad(Val1);
726
0
  llvm::AtomicRMWInst *RMWI =
727
0
      CGF.Builder.CreateAtomicRMW(Op, Ptr, LoadVal1, Order, Scope);
728
0
  RMWI->setVolatile(E->isVolatile());
729
730
  // For __atomic_*_fetch operations, perform the operation again to
731
  // determine the value which was written.
732
0
  llvm::Value *Result = RMWI;
733
0
  if (PostOpMinMax)
734
0
    Result = EmitPostAtomicMinMax(CGF.Builder, E->getOp(),
735
0
                                  E->getValueType()->isSignedIntegerType(),
736
0
                                  RMWI, LoadVal1);
737
0
  else if (PostOp)
738
0
    Result = CGF.Builder.CreateBinOp((llvm::Instruction::BinaryOps)PostOp, RMWI,
739
0
                                     LoadVal1);
740
0
  if (E->getOp() == AtomicExpr::AO__atomic_nand_fetch ||
741
0
      E->getOp() == AtomicExpr::AO__scoped_atomic_nand_fetch)
742
0
    Result = CGF.Builder.CreateNot(Result);
743
0
  CGF.Builder.CreateStore(Result, Dest);
744
0
}
745
746
// This function emits any expression (scalar, complex, or aggregate)
747
// into a temporary alloca.
748
static Address
749
0
EmitValToTemp(CodeGenFunction &CGF, Expr *E) {
750
0
  Address DeclPtr = CGF.CreateMemTemp(E->getType(), ".atomictmp");
751
0
  CGF.EmitAnyExprToMem(E, DeclPtr, E->getType().getQualifiers(),
752
0
                       /*Init*/ true);
753
0
  return DeclPtr;
754
0
}
755
756
static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *Expr, Address Dest,
757
                         Address Ptr, Address Val1, Address Val2,
758
                         llvm::Value *IsWeak, llvm::Value *FailureOrder,
759
                         uint64_t Size, llvm::AtomicOrdering Order,
760
0
                         llvm::Value *Scope) {
761
0
  auto ScopeModel = Expr->getScopeModel();
762
763
  // LLVM atomic instructions always have synch scope. If clang atomic
764
  // expression has no scope operand, use default LLVM synch scope.
765
0
  if (!ScopeModel) {
766
0
    EmitAtomicOp(CGF, Expr, Dest, Ptr, Val1, Val2, IsWeak, FailureOrder, Size,
767
0
                 Order, CGF.CGM.getLLVMContext().getOrInsertSyncScopeID(""));
768
0
    return;
769
0
  }
770
771
  // Handle constant scope.
772
0
  if (auto SC = dyn_cast<llvm::ConstantInt>(Scope)) {
773
0
    auto SCID = CGF.getTargetHooks().getLLVMSyncScopeID(
774
0
        CGF.CGM.getLangOpts(), ScopeModel->map(SC->getZExtValue()),
775
0
        Order, CGF.CGM.getLLVMContext());
776
0
    EmitAtomicOp(CGF, Expr, Dest, Ptr, Val1, Val2, IsWeak, FailureOrder, Size,
777
0
                 Order, SCID);
778
0
    return;
779
0
  }
780
781
  // Handle non-constant scope.
782
0
  auto &Builder = CGF.Builder;
783
0
  auto Scopes = ScopeModel->getRuntimeValues();
784
0
  llvm::DenseMap<unsigned, llvm::BasicBlock *> BB;
785
0
  for (auto S : Scopes)
786
0
    BB[S] = CGF.createBasicBlock(getAsString(ScopeModel->map(S)), CGF.CurFn);
787
788
0
  llvm::BasicBlock *ContBB =
789
0
      CGF.createBasicBlock("atomic.scope.continue", CGF.CurFn);
790
791
0
  auto *SC = Builder.CreateIntCast(Scope, Builder.getInt32Ty(), false);
792
  // If unsupported synch scope is encountered at run time, assume a fallback
793
  // synch scope value.
794
0
  auto FallBack = ScopeModel->getFallBackValue();
795
0
  llvm::SwitchInst *SI = Builder.CreateSwitch(SC, BB[FallBack]);
796
0
  for (auto S : Scopes) {
797
0
    auto *B = BB[S];
798
0
    if (S != FallBack)
799
0
      SI->addCase(Builder.getInt32(S), B);
800
801
0
    Builder.SetInsertPoint(B);
802
0
    EmitAtomicOp(CGF, Expr, Dest, Ptr, Val1, Val2, IsWeak, FailureOrder, Size,
803
0
                 Order,
804
0
                 CGF.getTargetHooks().getLLVMSyncScopeID(CGF.CGM.getLangOpts(),
805
0
                                                         ScopeModel->map(S),
806
0
                                                         Order,
807
0
                                                         CGF.getLLVMContext()));
808
0
    Builder.CreateBr(ContBB);
809
0
  }
810
811
0
  Builder.SetInsertPoint(ContBB);
812
0
}
813
814
static void
815
AddDirectArgument(CodeGenFunction &CGF, CallArgList &Args,
816
                  bool UseOptimizedLibcall, llvm::Value *Val, QualType ValTy,
817
0
                  SourceLocation Loc, CharUnits SizeInChars) {
818
0
  if (UseOptimizedLibcall) {
819
    // Load value and pass it to the function directly.
820
0
    CharUnits Align = CGF.getContext().getTypeAlignInChars(ValTy);
821
0
    int64_t SizeInBits = CGF.getContext().toBits(SizeInChars);
822
0
    ValTy =
823
0
        CGF.getContext().getIntTypeForBitwidth(SizeInBits, /*Signed=*/false);
824
0
    llvm::Type *ITy = llvm::IntegerType::get(CGF.getLLVMContext(), SizeInBits);
825
0
    Address Ptr = Address(Val, ITy, Align);
826
0
    Val = CGF.EmitLoadOfScalar(Ptr, false,
827
0
                               CGF.getContext().getPointerType(ValTy),
828
0
                               Loc);
829
    // Coerce the value into an appropriately sized integer type.
830
0
    Args.add(RValue::get(Val), ValTy);
831
0
  } else {
832
    // Non-optimized functions always take a reference.
833
0
    Args.add(RValue::get(Val), CGF.getContext().VoidPtrTy);
834
0
  }
835
0
}
836
837
0
RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
838
0
  QualType AtomicTy = E->getPtr()->getType()->getPointeeType();
839
0
  QualType MemTy = AtomicTy;
840
0
  if (const AtomicType *AT = AtomicTy->getAs<AtomicType>())
841
0
    MemTy = AT->getValueType();
842
0
  llvm::Value *IsWeak = nullptr, *OrderFail = nullptr;
843
844
0
  Address Val1 = Address::invalid();
845
0
  Address Val2 = Address::invalid();
846
0
  Address Dest = Address::invalid();
847
0
  Address Ptr = EmitPointerWithAlignment(E->getPtr());
848
849
0
  if (E->getOp() == AtomicExpr::AO__c11_atomic_init ||
850
0
      E->getOp() == AtomicExpr::AO__opencl_atomic_init) {
851
0
    LValue lvalue = MakeAddrLValue(Ptr, AtomicTy);
852
0
    EmitAtomicInit(E->getVal1(), lvalue);
853
0
    return RValue::get(nullptr);
854
0
  }
855
856
0
  auto TInfo = getContext().getTypeInfoInChars(AtomicTy);
857
0
  uint64_t Size = TInfo.Width.getQuantity();
858
0
  unsigned MaxInlineWidthInBits = getTarget().getMaxAtomicInlineWidth();
859
860
0
  bool Oversized = getContext().toBits(TInfo.Width) > MaxInlineWidthInBits;
861
0
  bool Misaligned = (Ptr.getAlignment() % TInfo.Width) != 0;
862
0
  bool UseLibcall = Misaligned | Oversized;
863
0
  bool ShouldCastToIntPtrTy = true;
864
865
0
  CharUnits MaxInlineWidth =
866
0
      getContext().toCharUnitsFromBits(MaxInlineWidthInBits);
867
868
0
  DiagnosticsEngine &Diags = CGM.getDiags();
869
870
0
  if (Misaligned) {
871
0
    Diags.Report(E->getBeginLoc(), diag::warn_atomic_op_misaligned)
872
0
        << (int)TInfo.Width.getQuantity()
873
0
        << (int)Ptr.getAlignment().getQuantity();
874
0
  }
875
876
0
  if (Oversized) {
877
0
    Diags.Report(E->getBeginLoc(), diag::warn_atomic_op_oversized)
878
0
        << (int)TInfo.Width.getQuantity() << (int)MaxInlineWidth.getQuantity();
879
0
  }
880
881
0
  llvm::Value *Order = EmitScalarExpr(E->getOrder());
882
0
  llvm::Value *Scope =
883
0
      E->getScopeModel() ? EmitScalarExpr(E->getScope()) : nullptr;
884
885
0
  switch (E->getOp()) {
886
0
  case AtomicExpr::AO__c11_atomic_init:
887
0
  case AtomicExpr::AO__opencl_atomic_init:
888
0
    llvm_unreachable("Already handled above with EmitAtomicInit!");
889
890
0
  case AtomicExpr::AO__atomic_load_n:
891
0
  case AtomicExpr::AO__scoped_atomic_load_n:
892
0
  case AtomicExpr::AO__c11_atomic_load:
893
0
  case AtomicExpr::AO__opencl_atomic_load:
894
0
  case AtomicExpr::AO__hip_atomic_load:
895
0
    break;
896
897
0
  case AtomicExpr::AO__atomic_load:
898
0
  case AtomicExpr::AO__scoped_atomic_load:
899
0
    Dest = EmitPointerWithAlignment(E->getVal1());
900
0
    break;
901
902
0
  case AtomicExpr::AO__atomic_store:
903
0
  case AtomicExpr::AO__scoped_atomic_store:
904
0
    Val1 = EmitPointerWithAlignment(E->getVal1());
905
0
    break;
906
907
0
  case AtomicExpr::AO__atomic_exchange:
908
0
  case AtomicExpr::AO__scoped_atomic_exchange:
909
0
    Val1 = EmitPointerWithAlignment(E->getVal1());
910
0
    Dest = EmitPointerWithAlignment(E->getVal2());
911
0
    break;
912
913
0
  case AtomicExpr::AO__atomic_compare_exchange:
914
0
  case AtomicExpr::AO__atomic_compare_exchange_n:
915
0
  case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
916
0
  case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
917
0
  case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
918
0
  case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
919
0
  case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
920
0
  case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
921
0
  case AtomicExpr::AO__scoped_atomic_compare_exchange:
922
0
  case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
923
0
    Val1 = EmitPointerWithAlignment(E->getVal1());
924
0
    if (E->getOp() == AtomicExpr::AO__atomic_compare_exchange ||
925
0
        E->getOp() == AtomicExpr::AO__scoped_atomic_compare_exchange)
926
0
      Val2 = EmitPointerWithAlignment(E->getVal2());
927
0
    else
928
0
      Val2 = EmitValToTemp(*this, E->getVal2());
929
0
    OrderFail = EmitScalarExpr(E->getOrderFail());
930
0
    if (E->getOp() == AtomicExpr::AO__atomic_compare_exchange_n ||
931
0
        E->getOp() == AtomicExpr::AO__atomic_compare_exchange ||
932
0
        E->getOp() == AtomicExpr::AO__scoped_atomic_compare_exchange_n ||
933
0
        E->getOp() == AtomicExpr::AO__scoped_atomic_compare_exchange)
934
0
      IsWeak = EmitScalarExpr(E->getWeak());
935
0
    break;
936
937
0
  case AtomicExpr::AO__c11_atomic_fetch_add:
938
0
  case AtomicExpr::AO__c11_atomic_fetch_sub:
939
0
  case AtomicExpr::AO__hip_atomic_fetch_add:
940
0
  case AtomicExpr::AO__hip_atomic_fetch_sub:
941
0
  case AtomicExpr::AO__opencl_atomic_fetch_add:
942
0
  case AtomicExpr::AO__opencl_atomic_fetch_sub:
943
0
    if (MemTy->isPointerType()) {
944
      // For pointer arithmetic, we're required to do a bit of math:
945
      // adding 1 to an int* is not the same as adding 1 to a uintptr_t.
946
      // ... but only for the C11 builtins. The GNU builtins expect the
947
      // user to multiply by sizeof(T).
948
0
      QualType Val1Ty = E->getVal1()->getType();
949
0
      llvm::Value *Val1Scalar = EmitScalarExpr(E->getVal1());
950
0
      CharUnits PointeeIncAmt =
951
0
          getContext().getTypeSizeInChars(MemTy->getPointeeType());
952
0
      Val1Scalar = Builder.CreateMul(Val1Scalar, CGM.getSize(PointeeIncAmt));
953
0
      auto Temp = CreateMemTemp(Val1Ty, ".atomictmp");
954
0
      Val1 = Temp;
955
0
      EmitStoreOfScalar(Val1Scalar, MakeAddrLValue(Temp, Val1Ty));
956
0
      break;
957
0
    }
958
0
    [[fallthrough]];
959
0
  case AtomicExpr::AO__atomic_fetch_add:
960
0
  case AtomicExpr::AO__atomic_fetch_max:
961
0
  case AtomicExpr::AO__atomic_fetch_min:
962
0
  case AtomicExpr::AO__atomic_fetch_sub:
963
0
  case AtomicExpr::AO__atomic_add_fetch:
964
0
  case AtomicExpr::AO__atomic_max_fetch:
965
0
  case AtomicExpr::AO__atomic_min_fetch:
966
0
  case AtomicExpr::AO__atomic_sub_fetch:
967
0
  case AtomicExpr::AO__c11_atomic_fetch_max:
968
0
  case AtomicExpr::AO__c11_atomic_fetch_min:
969
0
  case AtomicExpr::AO__opencl_atomic_fetch_max:
970
0
  case AtomicExpr::AO__opencl_atomic_fetch_min:
971
0
  case AtomicExpr::AO__hip_atomic_fetch_max:
972
0
  case AtomicExpr::AO__hip_atomic_fetch_min:
973
0
  case AtomicExpr::AO__scoped_atomic_fetch_add:
974
0
  case AtomicExpr::AO__scoped_atomic_fetch_max:
975
0
  case AtomicExpr::AO__scoped_atomic_fetch_min:
976
0
  case AtomicExpr::AO__scoped_atomic_fetch_sub:
977
0
  case AtomicExpr::AO__scoped_atomic_add_fetch:
978
0
  case AtomicExpr::AO__scoped_atomic_max_fetch:
979
0
  case AtomicExpr::AO__scoped_atomic_min_fetch:
980
0
  case AtomicExpr::AO__scoped_atomic_sub_fetch:
981
0
    ShouldCastToIntPtrTy = !MemTy->isFloatingType();
982
0
    [[fallthrough]];
983
984
0
  case AtomicExpr::AO__atomic_fetch_and:
985
0
  case AtomicExpr::AO__atomic_fetch_nand:
986
0
  case AtomicExpr::AO__atomic_fetch_or:
987
0
  case AtomicExpr::AO__atomic_fetch_xor:
988
0
  case AtomicExpr::AO__atomic_and_fetch:
989
0
  case AtomicExpr::AO__atomic_nand_fetch:
990
0
  case AtomicExpr::AO__atomic_or_fetch:
991
0
  case AtomicExpr::AO__atomic_xor_fetch:
992
0
  case AtomicExpr::AO__atomic_store_n:
993
0
  case AtomicExpr::AO__atomic_exchange_n:
994
0
  case AtomicExpr::AO__c11_atomic_fetch_and:
995
0
  case AtomicExpr::AO__c11_atomic_fetch_nand:
996
0
  case AtomicExpr::AO__c11_atomic_fetch_or:
997
0
  case AtomicExpr::AO__c11_atomic_fetch_xor:
998
0
  case AtomicExpr::AO__c11_atomic_store:
999
0
  case AtomicExpr::AO__c11_atomic_exchange:
1000
0
  case AtomicExpr::AO__hip_atomic_fetch_and:
1001
0
  case AtomicExpr::AO__hip_atomic_fetch_or:
1002
0
  case AtomicExpr::AO__hip_atomic_fetch_xor:
1003
0
  case AtomicExpr::AO__hip_atomic_store:
1004
0
  case AtomicExpr::AO__hip_atomic_exchange:
1005
0
  case AtomicExpr::AO__opencl_atomic_fetch_and:
1006
0
  case AtomicExpr::AO__opencl_atomic_fetch_or:
1007
0
  case AtomicExpr::AO__opencl_atomic_fetch_xor:
1008
0
  case AtomicExpr::AO__opencl_atomic_store:
1009
0
  case AtomicExpr::AO__opencl_atomic_exchange:
1010
0
  case AtomicExpr::AO__scoped_atomic_fetch_and:
1011
0
  case AtomicExpr::AO__scoped_atomic_fetch_nand:
1012
0
  case AtomicExpr::AO__scoped_atomic_fetch_or:
1013
0
  case AtomicExpr::AO__scoped_atomic_fetch_xor:
1014
0
  case AtomicExpr::AO__scoped_atomic_and_fetch:
1015
0
  case AtomicExpr::AO__scoped_atomic_nand_fetch:
1016
0
  case AtomicExpr::AO__scoped_atomic_or_fetch:
1017
0
  case AtomicExpr::AO__scoped_atomic_xor_fetch:
1018
0
  case AtomicExpr::AO__scoped_atomic_store_n:
1019
0
  case AtomicExpr::AO__scoped_atomic_exchange_n:
1020
0
    Val1 = EmitValToTemp(*this, E->getVal1());
1021
0
    break;
1022
0
  }
1023
1024
0
  QualType RValTy = E->getType().getUnqualifiedType();
1025
1026
  // The inlined atomics only function on iN types, where N is a power of 2. We
1027
  // need to make sure (via temporaries if necessary) that all incoming values
1028
  // are compatible.
1029
0
  LValue AtomicVal = MakeAddrLValue(Ptr, AtomicTy);
1030
0
  AtomicInfo Atomics(*this, AtomicVal);
1031
1032
0
  if (ShouldCastToIntPtrTy) {
1033
0
    Ptr = Atomics.castToAtomicIntPointer(Ptr);
1034
0
    if (Val1.isValid())
1035
0
      Val1 = Atomics.convertToAtomicIntPointer(Val1);
1036
0
    if (Val2.isValid())
1037
0
      Val2 = Atomics.convertToAtomicIntPointer(Val2);
1038
0
  }
1039
0
  if (Dest.isValid()) {
1040
0
    if (ShouldCastToIntPtrTy)
1041
0
      Dest = Atomics.castToAtomicIntPointer(Dest);
1042
0
  } else if (E->isCmpXChg())
1043
0
    Dest = CreateMemTemp(RValTy, "cmpxchg.bool");
1044
0
  else if (!RValTy->isVoidType()) {
1045
0
    Dest = Atomics.CreateTempAlloca();
1046
0
    if (ShouldCastToIntPtrTy)
1047
0
      Dest = Atomics.castToAtomicIntPointer(Dest);
1048
0
  }
1049
1050
  // Use a library call.  See: http://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary .
1051
0
  if (UseLibcall) {
1052
0
    bool UseOptimizedLibcall = false;
1053
0
    switch (E->getOp()) {
1054
0
    case AtomicExpr::AO__c11_atomic_init:
1055
0
    case AtomicExpr::AO__opencl_atomic_init:
1056
0
      llvm_unreachable("Already handled above with EmitAtomicInit!");
1057
1058
0
    case AtomicExpr::AO__atomic_fetch_add:
1059
0
    case AtomicExpr::AO__atomic_fetch_and:
1060
0
    case AtomicExpr::AO__atomic_fetch_max:
1061
0
    case AtomicExpr::AO__atomic_fetch_min:
1062
0
    case AtomicExpr::AO__atomic_fetch_nand:
1063
0
    case AtomicExpr::AO__atomic_fetch_or:
1064
0
    case AtomicExpr::AO__atomic_fetch_sub:
1065
0
    case AtomicExpr::AO__atomic_fetch_xor:
1066
0
    case AtomicExpr::AO__atomic_add_fetch:
1067
0
    case AtomicExpr::AO__atomic_and_fetch:
1068
0
    case AtomicExpr::AO__atomic_max_fetch:
1069
0
    case AtomicExpr::AO__atomic_min_fetch:
1070
0
    case AtomicExpr::AO__atomic_nand_fetch:
1071
0
    case AtomicExpr::AO__atomic_or_fetch:
1072
0
    case AtomicExpr::AO__atomic_sub_fetch:
1073
0
    case AtomicExpr::AO__atomic_xor_fetch:
1074
0
    case AtomicExpr::AO__c11_atomic_fetch_add:
1075
0
    case AtomicExpr::AO__c11_atomic_fetch_and:
1076
0
    case AtomicExpr::AO__c11_atomic_fetch_max:
1077
0
    case AtomicExpr::AO__c11_atomic_fetch_min:
1078
0
    case AtomicExpr::AO__c11_atomic_fetch_nand:
1079
0
    case AtomicExpr::AO__c11_atomic_fetch_or:
1080
0
    case AtomicExpr::AO__c11_atomic_fetch_sub:
1081
0
    case AtomicExpr::AO__c11_atomic_fetch_xor:
1082
0
    case AtomicExpr::AO__hip_atomic_fetch_add:
1083
0
    case AtomicExpr::AO__hip_atomic_fetch_and:
1084
0
    case AtomicExpr::AO__hip_atomic_fetch_max:
1085
0
    case AtomicExpr::AO__hip_atomic_fetch_min:
1086
0
    case AtomicExpr::AO__hip_atomic_fetch_or:
1087
0
    case AtomicExpr::AO__hip_atomic_fetch_sub:
1088
0
    case AtomicExpr::AO__hip_atomic_fetch_xor:
1089
0
    case AtomicExpr::AO__opencl_atomic_fetch_add:
1090
0
    case AtomicExpr::AO__opencl_atomic_fetch_and:
1091
0
    case AtomicExpr::AO__opencl_atomic_fetch_max:
1092
0
    case AtomicExpr::AO__opencl_atomic_fetch_min:
1093
0
    case AtomicExpr::AO__opencl_atomic_fetch_or:
1094
0
    case AtomicExpr::AO__opencl_atomic_fetch_sub:
1095
0
    case AtomicExpr::AO__opencl_atomic_fetch_xor:
1096
0
    case AtomicExpr::AO__scoped_atomic_fetch_add:
1097
0
    case AtomicExpr::AO__scoped_atomic_fetch_and:
1098
0
    case AtomicExpr::AO__scoped_atomic_fetch_max:
1099
0
    case AtomicExpr::AO__scoped_atomic_fetch_min:
1100
0
    case AtomicExpr::AO__scoped_atomic_fetch_nand:
1101
0
    case AtomicExpr::AO__scoped_atomic_fetch_or:
1102
0
    case AtomicExpr::AO__scoped_atomic_fetch_sub:
1103
0
    case AtomicExpr::AO__scoped_atomic_fetch_xor:
1104
0
    case AtomicExpr::AO__scoped_atomic_add_fetch:
1105
0
    case AtomicExpr::AO__scoped_atomic_and_fetch:
1106
0
    case AtomicExpr::AO__scoped_atomic_max_fetch:
1107
0
    case AtomicExpr::AO__scoped_atomic_min_fetch:
1108
0
    case AtomicExpr::AO__scoped_atomic_nand_fetch:
1109
0
    case AtomicExpr::AO__scoped_atomic_or_fetch:
1110
0
    case AtomicExpr::AO__scoped_atomic_sub_fetch:
1111
0
    case AtomicExpr::AO__scoped_atomic_xor_fetch:
1112
      // For these, only library calls for certain sizes exist.
1113
0
      UseOptimizedLibcall = true;
1114
0
      break;
1115
1116
0
    case AtomicExpr::AO__atomic_load:
1117
0
    case AtomicExpr::AO__atomic_store:
1118
0
    case AtomicExpr::AO__atomic_exchange:
1119
0
    case AtomicExpr::AO__atomic_compare_exchange:
1120
0
    case AtomicExpr::AO__scoped_atomic_load:
1121
0
    case AtomicExpr::AO__scoped_atomic_store:
1122
0
    case AtomicExpr::AO__scoped_atomic_exchange:
1123
0
    case AtomicExpr::AO__scoped_atomic_compare_exchange:
1124
      // Use the generic version if we don't know that the operand will be
1125
      // suitably aligned for the optimized version.
1126
0
      if (Misaligned)
1127
0
        break;
1128
0
      [[fallthrough]];
1129
0
    case AtomicExpr::AO__atomic_load_n:
1130
0
    case AtomicExpr::AO__atomic_store_n:
1131
0
    case AtomicExpr::AO__atomic_exchange_n:
1132
0
    case AtomicExpr::AO__atomic_compare_exchange_n:
1133
0
    case AtomicExpr::AO__c11_atomic_load:
1134
0
    case AtomicExpr::AO__c11_atomic_store:
1135
0
    case AtomicExpr::AO__c11_atomic_exchange:
1136
0
    case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
1137
0
    case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
1138
0
    case AtomicExpr::AO__hip_atomic_load:
1139
0
    case AtomicExpr::AO__hip_atomic_store:
1140
0
    case AtomicExpr::AO__hip_atomic_exchange:
1141
0
    case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
1142
0
    case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
1143
0
    case AtomicExpr::AO__opencl_atomic_load:
1144
0
    case AtomicExpr::AO__opencl_atomic_store:
1145
0
    case AtomicExpr::AO__opencl_atomic_exchange:
1146
0
    case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
1147
0
    case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
1148
0
    case AtomicExpr::AO__scoped_atomic_load_n:
1149
0
    case AtomicExpr::AO__scoped_atomic_store_n:
1150
0
    case AtomicExpr::AO__scoped_atomic_exchange_n:
1151
0
    case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
1152
      // Only use optimized library calls for sizes for which they exist.
1153
      // FIXME: Size == 16 optimized library functions exist too.
1154
0
      if (Size == 1 || Size == 2 || Size == 4 || Size == 8)
1155
0
        UseOptimizedLibcall = true;
1156
0
      break;
1157
0
    }
1158
1159
0
    CallArgList Args;
1160
0
    if (!UseOptimizedLibcall) {
1161
      // For non-optimized library calls, the size is the first parameter
1162
0
      Args.add(RValue::get(llvm::ConstantInt::get(SizeTy, Size)),
1163
0
               getContext().getSizeType());
1164
0
    }
1165
    // Atomic address is the first or second parameter
1166
    // The OpenCL atomic library functions only accept pointer arguments to
1167
    // generic address space.
1168
0
    auto CastToGenericAddrSpace = [&](llvm::Value *V, QualType PT) {
1169
0
      if (!E->isOpenCL())
1170
0
        return V;
1171
0
      auto AS = PT->castAs<PointerType>()->getPointeeType().getAddressSpace();
1172
0
      if (AS == LangAS::opencl_generic)
1173
0
        return V;
1174
0
      auto DestAS = getContext().getTargetAddressSpace(LangAS::opencl_generic);
1175
0
      auto *DestType = llvm::PointerType::get(getLLVMContext(), DestAS);
1176
1177
0
      return getTargetHooks().performAddrSpaceCast(
1178
0
          *this, V, AS, LangAS::opencl_generic, DestType, false);
1179
0
    };
1180
1181
0
    Args.add(RValue::get(CastToGenericAddrSpace(Ptr.getPointer(),
1182
0
                                                E->getPtr()->getType())),
1183
0
             getContext().VoidPtrTy);
1184
1185
0
    std::string LibCallName;
1186
0
    QualType LoweredMemTy =
1187
0
      MemTy->isPointerType() ? getContext().getIntPtrType() : MemTy;
1188
0
    QualType RetTy;
1189
0
    bool HaveRetTy = false;
1190
0
    llvm::Instruction::BinaryOps PostOp = (llvm::Instruction::BinaryOps)0;
1191
0
    bool PostOpMinMax = false;
1192
0
    switch (E->getOp()) {
1193
0
    case AtomicExpr::AO__c11_atomic_init:
1194
0
    case AtomicExpr::AO__opencl_atomic_init:
1195
0
      llvm_unreachable("Already handled!");
1196
1197
    // There is only one libcall for compare an exchange, because there is no
1198
    // optimisation benefit possible from a libcall version of a weak compare
1199
    // and exchange.
1200
    // bool __atomic_compare_exchange(size_t size, void *mem, void *expected,
1201
    //                                void *desired, int success, int failure)
1202
    // bool __atomic_compare_exchange_N(T *mem, T *expected, T desired,
1203
    //                                  int success, int failure)
1204
0
    case AtomicExpr::AO__atomic_compare_exchange:
1205
0
    case AtomicExpr::AO__atomic_compare_exchange_n:
1206
0
    case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
1207
0
    case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
1208
0
    case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
1209
0
    case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
1210
0
    case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
1211
0
    case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
1212
0
    case AtomicExpr::AO__scoped_atomic_compare_exchange:
1213
0
    case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
1214
0
      LibCallName = "__atomic_compare_exchange";
1215
0
      RetTy = getContext().BoolTy;
1216
0
      HaveRetTy = true;
1217
0
      Args.add(RValue::get(CastToGenericAddrSpace(Val1.getPointer(),
1218
0
                                                  E->getVal1()->getType())),
1219
0
               getContext().VoidPtrTy);
1220
0
      AddDirectArgument(*this, Args, UseOptimizedLibcall, Val2.getPointer(),
1221
0
                        MemTy, E->getExprLoc(), TInfo.Width);
1222
0
      Args.add(RValue::get(Order), getContext().IntTy);
1223
0
      Order = OrderFail;
1224
0
      break;
1225
    // void __atomic_exchange(size_t size, void *mem, void *val, void *return,
1226
    //                        int order)
1227
    // T __atomic_exchange_N(T *mem, T val, int order)
1228
0
    case AtomicExpr::AO__atomic_exchange:
1229
0
    case AtomicExpr::AO__atomic_exchange_n:
1230
0
    case AtomicExpr::AO__c11_atomic_exchange:
1231
0
    case AtomicExpr::AO__hip_atomic_exchange:
1232
0
    case AtomicExpr::AO__opencl_atomic_exchange:
1233
0
    case AtomicExpr::AO__scoped_atomic_exchange:
1234
0
    case AtomicExpr::AO__scoped_atomic_exchange_n:
1235
0
      LibCallName = "__atomic_exchange";
1236
0
      AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(),
1237
0
                        MemTy, E->getExprLoc(), TInfo.Width);
1238
0
      break;
1239
    // void __atomic_store(size_t size, void *mem, void *val, int order)
1240
    // void __atomic_store_N(T *mem, T val, int order)
1241
0
    case AtomicExpr::AO__atomic_store:
1242
0
    case AtomicExpr::AO__atomic_store_n:
1243
0
    case AtomicExpr::AO__c11_atomic_store:
1244
0
    case AtomicExpr::AO__hip_atomic_store:
1245
0
    case AtomicExpr::AO__opencl_atomic_store:
1246
0
    case AtomicExpr::AO__scoped_atomic_store:
1247
0
    case AtomicExpr::AO__scoped_atomic_store_n:
1248
0
      LibCallName = "__atomic_store";
1249
0
      RetTy = getContext().VoidTy;
1250
0
      HaveRetTy = true;
1251
0
      AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(),
1252
0
                        MemTy, E->getExprLoc(), TInfo.Width);
1253
0
      break;
1254
    // void __atomic_load(size_t size, void *mem, void *return, int order)
1255
    // T __atomic_load_N(T *mem, int order)
1256
0
    case AtomicExpr::AO__atomic_load:
1257
0
    case AtomicExpr::AO__atomic_load_n:
1258
0
    case AtomicExpr::AO__c11_atomic_load:
1259
0
    case AtomicExpr::AO__hip_atomic_load:
1260
0
    case AtomicExpr::AO__opencl_atomic_load:
1261
0
    case AtomicExpr::AO__scoped_atomic_load:
1262
0
    case AtomicExpr::AO__scoped_atomic_load_n:
1263
0
      LibCallName = "__atomic_load";
1264
0
      break;
1265
    // T __atomic_add_fetch_N(T *mem, T val, int order)
1266
    // T __atomic_fetch_add_N(T *mem, T val, int order)
1267
0
    case AtomicExpr::AO__atomic_add_fetch:
1268
0
    case AtomicExpr::AO__scoped_atomic_add_fetch:
1269
0
      PostOp = llvm::Instruction::Add;
1270
0
      [[fallthrough]];
1271
0
    case AtomicExpr::AO__atomic_fetch_add:
1272
0
    case AtomicExpr::AO__c11_atomic_fetch_add:
1273
0
    case AtomicExpr::AO__hip_atomic_fetch_add:
1274
0
    case AtomicExpr::AO__opencl_atomic_fetch_add:
1275
0
    case AtomicExpr::AO__scoped_atomic_fetch_add:
1276
0
      LibCallName = "__atomic_fetch_add";
1277
0
      AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(),
1278
0
                        LoweredMemTy, E->getExprLoc(), TInfo.Width);
1279
0
      break;
1280
    // T __atomic_and_fetch_N(T *mem, T val, int order)
1281
    // T __atomic_fetch_and_N(T *mem, T val, int order)
1282
0
    case AtomicExpr::AO__atomic_and_fetch:
1283
0
    case AtomicExpr::AO__scoped_atomic_and_fetch:
1284
0
      PostOp = llvm::Instruction::And;
1285
0
      [[fallthrough]];
1286
0
    case AtomicExpr::AO__atomic_fetch_and:
1287
0
    case AtomicExpr::AO__c11_atomic_fetch_and:
1288
0
    case AtomicExpr::AO__hip_atomic_fetch_and:
1289
0
    case AtomicExpr::AO__opencl_atomic_fetch_and:
1290
0
    case AtomicExpr::AO__scoped_atomic_fetch_and:
1291
0
      LibCallName = "__atomic_fetch_and";
1292
0
      AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(),
1293
0
                        MemTy, E->getExprLoc(), TInfo.Width);
1294
0
      break;
1295
    // T __atomic_or_fetch_N(T *mem, T val, int order)
1296
    // T __atomic_fetch_or_N(T *mem, T val, int order)
1297
0
    case AtomicExpr::AO__atomic_or_fetch:
1298
0
    case AtomicExpr::AO__scoped_atomic_or_fetch:
1299
0
      PostOp = llvm::Instruction::Or;
1300
0
      [[fallthrough]];
1301
0
    case AtomicExpr::AO__atomic_fetch_or:
1302
0
    case AtomicExpr::AO__c11_atomic_fetch_or:
1303
0
    case AtomicExpr::AO__hip_atomic_fetch_or:
1304
0
    case AtomicExpr::AO__opencl_atomic_fetch_or:
1305
0
    case AtomicExpr::AO__scoped_atomic_fetch_or:
1306
0
      LibCallName = "__atomic_fetch_or";
1307
0
      AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(),
1308
0
                        MemTy, E->getExprLoc(), TInfo.Width);
1309
0
      break;
1310
    // T __atomic_sub_fetch_N(T *mem, T val, int order)
1311
    // T __atomic_fetch_sub_N(T *mem, T val, int order)
1312
0
    case AtomicExpr::AO__atomic_sub_fetch:
1313
0
    case AtomicExpr::AO__scoped_atomic_sub_fetch:
1314
0
      PostOp = llvm::Instruction::Sub;
1315
0
      [[fallthrough]];
1316
0
    case AtomicExpr::AO__atomic_fetch_sub:
1317
0
    case AtomicExpr::AO__c11_atomic_fetch_sub:
1318
0
    case AtomicExpr::AO__hip_atomic_fetch_sub:
1319
0
    case AtomicExpr::AO__opencl_atomic_fetch_sub:
1320
0
    case AtomicExpr::AO__scoped_atomic_fetch_sub:
1321
0
      LibCallName = "__atomic_fetch_sub";
1322
0
      AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(),
1323
0
                        LoweredMemTy, E->getExprLoc(), TInfo.Width);
1324
0
      break;
1325
    // T __atomic_xor_fetch_N(T *mem, T val, int order)
1326
    // T __atomic_fetch_xor_N(T *mem, T val, int order)
1327
0
    case AtomicExpr::AO__atomic_xor_fetch:
1328
0
    case AtomicExpr::AO__scoped_atomic_xor_fetch:
1329
0
      PostOp = llvm::Instruction::Xor;
1330
0
      [[fallthrough]];
1331
0
    case AtomicExpr::AO__atomic_fetch_xor:
1332
0
    case AtomicExpr::AO__c11_atomic_fetch_xor:
1333
0
    case AtomicExpr::AO__hip_atomic_fetch_xor:
1334
0
    case AtomicExpr::AO__opencl_atomic_fetch_xor:
1335
0
    case AtomicExpr::AO__scoped_atomic_fetch_xor:
1336
0
      LibCallName = "__atomic_fetch_xor";
1337
0
      AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(),
1338
0
                        MemTy, E->getExprLoc(), TInfo.Width);
1339
0
      break;
1340
0
    case AtomicExpr::AO__atomic_min_fetch:
1341
0
    case AtomicExpr::AO__scoped_atomic_min_fetch:
1342
0
      PostOpMinMax = true;
1343
0
      [[fallthrough]];
1344
0
    case AtomicExpr::AO__atomic_fetch_min:
1345
0
    case AtomicExpr::AO__c11_atomic_fetch_min:
1346
0
    case AtomicExpr::AO__scoped_atomic_fetch_min:
1347
0
    case AtomicExpr::AO__hip_atomic_fetch_min:
1348
0
    case AtomicExpr::AO__opencl_atomic_fetch_min:
1349
0
      LibCallName = E->getValueType()->isSignedIntegerType()
1350
0
                        ? "__atomic_fetch_min"
1351
0
                        : "__atomic_fetch_umin";
1352
0
      AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(),
1353
0
                        LoweredMemTy, E->getExprLoc(), TInfo.Width);
1354
0
      break;
1355
0
    case AtomicExpr::AO__atomic_max_fetch:
1356
0
    case AtomicExpr::AO__scoped_atomic_max_fetch:
1357
0
      PostOpMinMax = true;
1358
0
      [[fallthrough]];
1359
0
    case AtomicExpr::AO__atomic_fetch_max:
1360
0
    case AtomicExpr::AO__c11_atomic_fetch_max:
1361
0
    case AtomicExpr::AO__hip_atomic_fetch_max:
1362
0
    case AtomicExpr::AO__opencl_atomic_fetch_max:
1363
0
    case AtomicExpr::AO__scoped_atomic_fetch_max:
1364
0
      LibCallName = E->getValueType()->isSignedIntegerType()
1365
0
                        ? "__atomic_fetch_max"
1366
0
                        : "__atomic_fetch_umax";
1367
0
      AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(),
1368
0
                        LoweredMemTy, E->getExprLoc(), TInfo.Width);
1369
0
      break;
1370
    // T __atomic_nand_fetch_N(T *mem, T val, int order)
1371
    // T __atomic_fetch_nand_N(T *mem, T val, int order)
1372
0
    case AtomicExpr::AO__atomic_nand_fetch:
1373
0
    case AtomicExpr::AO__scoped_atomic_nand_fetch:
1374
0
      PostOp = llvm::Instruction::And; // the NOT is special cased below
1375
0
      [[fallthrough]];
1376
0
    case AtomicExpr::AO__atomic_fetch_nand:
1377
0
    case AtomicExpr::AO__c11_atomic_fetch_nand:
1378
0
    case AtomicExpr::AO__scoped_atomic_fetch_nand:
1379
0
      LibCallName = "__atomic_fetch_nand";
1380
0
      AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(),
1381
0
                        MemTy, E->getExprLoc(), TInfo.Width);
1382
0
      break;
1383
0
    }
1384
1385
0
    if (E->isOpenCL()) {
1386
0
      LibCallName = std::string("__opencl") +
1387
0
          StringRef(LibCallName).drop_front(1).str();
1388
1389
0
    }
1390
    // Optimized functions have the size in their name.
1391
0
    if (UseOptimizedLibcall)
1392
0
      LibCallName += "_" + llvm::utostr(Size);
1393
    // By default, assume we return a value of the atomic type.
1394
0
    if (!HaveRetTy) {
1395
0
      if (UseOptimizedLibcall) {
1396
        // Value is returned directly.
1397
        // The function returns an appropriately sized integer type.
1398
0
        RetTy = getContext().getIntTypeForBitwidth(
1399
0
            getContext().toBits(TInfo.Width), /*Signed=*/false);
1400
0
      } else {
1401
        // Value is returned through parameter before the order.
1402
0
        RetTy = getContext().VoidTy;
1403
0
        Args.add(RValue::get(Dest.getPointer()), getContext().VoidPtrTy);
1404
0
      }
1405
0
    }
1406
    // order is always the last parameter
1407
0
    Args.add(RValue::get(Order),
1408
0
             getContext().IntTy);
1409
0
    if (E->isOpenCL())
1410
0
      Args.add(RValue::get(Scope), getContext().IntTy);
1411
1412
    // PostOp is only needed for the atomic_*_fetch operations, and
1413
    // thus is only needed for and implemented in the
1414
    // UseOptimizedLibcall codepath.
1415
0
    assert(UseOptimizedLibcall || (!PostOp && !PostOpMinMax));
1416
1417
0
    RValue Res = emitAtomicLibcall(*this, LibCallName, RetTy, Args);
1418
    // The value is returned directly from the libcall.
1419
0
    if (E->isCmpXChg())
1420
0
      return Res;
1421
1422
    // The value is returned directly for optimized libcalls but the expr
1423
    // provided an out-param.
1424
0
    if (UseOptimizedLibcall && Res.getScalarVal()) {
1425
0
      llvm::Value *ResVal = Res.getScalarVal();
1426
0
      if (PostOpMinMax) {
1427
0
        llvm::Value *LoadVal1 = Args[1].getRValue(*this).getScalarVal();
1428
0
        ResVal = EmitPostAtomicMinMax(Builder, E->getOp(),
1429
0
                                      E->getValueType()->isSignedIntegerType(),
1430
0
                                      ResVal, LoadVal1);
1431
0
      } else if (PostOp) {
1432
0
        llvm::Value *LoadVal1 = Args[1].getRValue(*this).getScalarVal();
1433
0
        ResVal = Builder.CreateBinOp(PostOp, ResVal, LoadVal1);
1434
0
      }
1435
0
      if (E->getOp() == AtomicExpr::AO__atomic_nand_fetch ||
1436
0
          E->getOp() == AtomicExpr::AO__scoped_atomic_nand_fetch)
1437
0
        ResVal = Builder.CreateNot(ResVal);
1438
1439
0
      Builder.CreateStore(ResVal, Dest.withElementType(ResVal->getType()));
1440
0
    }
1441
1442
0
    if (RValTy->isVoidType())
1443
0
      return RValue::get(nullptr);
1444
1445
0
    return convertTempToRValue(Dest.withElementType(ConvertTypeForMem(RValTy)),
1446
0
                               RValTy, E->getExprLoc());
1447
0
  }
1448
1449
0
  bool IsStore = E->getOp() == AtomicExpr::AO__c11_atomic_store ||
1450
0
                 E->getOp() == AtomicExpr::AO__opencl_atomic_store ||
1451
0
                 E->getOp() == AtomicExpr::AO__hip_atomic_store ||
1452
0
                 E->getOp() == AtomicExpr::AO__atomic_store ||
1453
0
                 E->getOp() == AtomicExpr::AO__atomic_store_n ||
1454
0
                 E->getOp() == AtomicExpr::AO__scoped_atomic_store ||
1455
0
                 E->getOp() == AtomicExpr::AO__scoped_atomic_store_n;
1456
0
  bool IsLoad = E->getOp() == AtomicExpr::AO__c11_atomic_load ||
1457
0
                E->getOp() == AtomicExpr::AO__opencl_atomic_load ||
1458
0
                E->getOp() == AtomicExpr::AO__hip_atomic_load ||
1459
0
                E->getOp() == AtomicExpr::AO__atomic_load ||
1460
0
                E->getOp() == AtomicExpr::AO__atomic_load_n ||
1461
0
                E->getOp() == AtomicExpr::AO__scoped_atomic_load ||
1462
0
                E->getOp() == AtomicExpr::AO__scoped_atomic_load_n;
1463
1464
0
  if (isa<llvm::ConstantInt>(Order)) {
1465
0
    auto ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
1466
    // We should not ever get to a case where the ordering isn't a valid C ABI
1467
    // value, but it's hard to enforce that in general.
1468
0
    if (llvm::isValidAtomicOrderingCABI(ord))
1469
0
      switch ((llvm::AtomicOrderingCABI)ord) {
1470
0
      case llvm::AtomicOrderingCABI::relaxed:
1471
0
        EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1472
0
                     llvm::AtomicOrdering::Monotonic, Scope);
1473
0
        break;
1474
0
      case llvm::AtomicOrderingCABI::consume:
1475
0
      case llvm::AtomicOrderingCABI::acquire:
1476
0
        if (IsStore)
1477
0
          break; // Avoid crashing on code with undefined behavior
1478
0
        EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1479
0
                     llvm::AtomicOrdering::Acquire, Scope);
1480
0
        break;
1481
0
      case llvm::AtomicOrderingCABI::release:
1482
0
        if (IsLoad)
1483
0
          break; // Avoid crashing on code with undefined behavior
1484
0
        EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1485
0
                     llvm::AtomicOrdering::Release, Scope);
1486
0
        break;
1487
0
      case llvm::AtomicOrderingCABI::acq_rel:
1488
0
        if (IsLoad || IsStore)
1489
0
          break; // Avoid crashing on code with undefined behavior
1490
0
        EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1491
0
                     llvm::AtomicOrdering::AcquireRelease, Scope);
1492
0
        break;
1493
0
      case llvm::AtomicOrderingCABI::seq_cst:
1494
0
        EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1495
0
                     llvm::AtomicOrdering::SequentiallyConsistent, Scope);
1496
0
        break;
1497
0
      }
1498
0
    if (RValTy->isVoidType())
1499
0
      return RValue::get(nullptr);
1500
1501
0
    return convertTempToRValue(Dest.withElementType(ConvertTypeForMem(RValTy)),
1502
0
                               RValTy, E->getExprLoc());
1503
0
  }
1504
1505
  // Long case, when Order isn't obviously constant.
1506
1507
  // Create all the relevant BB's
1508
0
  llvm::BasicBlock *MonotonicBB = nullptr, *AcquireBB = nullptr,
1509
0
                   *ReleaseBB = nullptr, *AcqRelBB = nullptr,
1510
0
                   *SeqCstBB = nullptr;
1511
0
  MonotonicBB = createBasicBlock("monotonic", CurFn);
1512
0
  if (!IsStore)
1513
0
    AcquireBB = createBasicBlock("acquire", CurFn);
1514
0
  if (!IsLoad)
1515
0
    ReleaseBB = createBasicBlock("release", CurFn);
1516
0
  if (!IsLoad && !IsStore)
1517
0
    AcqRelBB = createBasicBlock("acqrel", CurFn);
1518
0
  SeqCstBB = createBasicBlock("seqcst", CurFn);
1519
0
  llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn);
1520
1521
  // Create the switch for the split
1522
  // MonotonicBB is arbitrarily chosen as the default case; in practice, this
1523
  // doesn't matter unless someone is crazy enough to use something that
1524
  // doesn't fold to a constant for the ordering.
1525
0
  Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false);
1526
0
  llvm::SwitchInst *SI = Builder.CreateSwitch(Order, MonotonicBB);
1527
1528
  // Emit all the different atomics
1529
0
  Builder.SetInsertPoint(MonotonicBB);
1530
0
  EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1531
0
               llvm::AtomicOrdering::Monotonic, Scope);
1532
0
  Builder.CreateBr(ContBB);
1533
0
  if (!IsStore) {
1534
0
    Builder.SetInsertPoint(AcquireBB);
1535
0
    EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1536
0
                 llvm::AtomicOrdering::Acquire, Scope);
1537
0
    Builder.CreateBr(ContBB);
1538
0
    SI->addCase(Builder.getInt32((int)llvm::AtomicOrderingCABI::consume),
1539
0
                AcquireBB);
1540
0
    SI->addCase(Builder.getInt32((int)llvm::AtomicOrderingCABI::acquire),
1541
0
                AcquireBB);
1542
0
  }
1543
0
  if (!IsLoad) {
1544
0
    Builder.SetInsertPoint(ReleaseBB);
1545
0
    EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1546
0
                 llvm::AtomicOrdering::Release, Scope);
1547
0
    Builder.CreateBr(ContBB);
1548
0
    SI->addCase(Builder.getInt32((int)llvm::AtomicOrderingCABI::release),
1549
0
                ReleaseBB);
1550
0
  }
1551
0
  if (!IsLoad && !IsStore) {
1552
0
    Builder.SetInsertPoint(AcqRelBB);
1553
0
    EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1554
0
                 llvm::AtomicOrdering::AcquireRelease, Scope);
1555
0
    Builder.CreateBr(ContBB);
1556
0
    SI->addCase(Builder.getInt32((int)llvm::AtomicOrderingCABI::acq_rel),
1557
0
                AcqRelBB);
1558
0
  }
1559
0
  Builder.SetInsertPoint(SeqCstBB);
1560
0
  EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1561
0
               llvm::AtomicOrdering::SequentiallyConsistent, Scope);
1562
0
  Builder.CreateBr(ContBB);
1563
0
  SI->addCase(Builder.getInt32((int)llvm::AtomicOrderingCABI::seq_cst),
1564
0
              SeqCstBB);
1565
1566
  // Cleanup and return
1567
0
  Builder.SetInsertPoint(ContBB);
1568
0
  if (RValTy->isVoidType())
1569
0
    return RValue::get(nullptr);
1570
1571
0
  assert(Atomics.getValueSizeInBits() <= Atomics.getAtomicSizeInBits());
1572
0
  return convertTempToRValue(Dest.withElementType(ConvertTypeForMem(RValTy)),
1573
0
                             RValTy, E->getExprLoc());
1574
0
}
1575
1576
0
Address AtomicInfo::castToAtomicIntPointer(Address addr) const {
1577
0
  llvm::IntegerType *ty =
1578
0
    llvm::IntegerType::get(CGF.getLLVMContext(), AtomicSizeInBits);
1579
0
  return addr.withElementType(ty);
1580
0
}
1581
1582
0
Address AtomicInfo::convertToAtomicIntPointer(Address Addr) const {
1583
0
  llvm::Type *Ty = Addr.getElementType();
1584
0
  uint64_t SourceSizeInBits = CGF.CGM.getDataLayout().getTypeSizeInBits(Ty);
1585
0
  if (SourceSizeInBits != AtomicSizeInBits) {
1586
0
    Address Tmp = CreateTempAlloca();
1587
0
    CGF.Builder.CreateMemCpy(Tmp, Addr,
1588
0
                             std::min(AtomicSizeInBits, SourceSizeInBits) / 8);
1589
0
    Addr = Tmp;
1590
0
  }
1591
1592
0
  return castToAtomicIntPointer(Addr);
1593
0
}
1594
1595
RValue AtomicInfo::convertAtomicTempToRValue(Address addr,
1596
                                             AggValueSlot resultSlot,
1597
                                             SourceLocation loc,
1598
0
                                             bool asValue) const {
1599
0
  if (LVal.isSimple()) {
1600
0
    if (EvaluationKind == TEK_Aggregate)
1601
0
      return resultSlot.asRValue();
1602
1603
    // Drill into the padding structure if we have one.
1604
0
    if (hasPadding())
1605
0
      addr = CGF.Builder.CreateStructGEP(addr, 0);
1606
1607
    // Otherwise, just convert the temporary to an r-value using the
1608
    // normal conversion routine.
1609
0
    return CGF.convertTempToRValue(addr, getValueType(), loc);
1610
0
  }
1611
0
  if (!asValue)
1612
    // Get RValue from temp memory as atomic for non-simple lvalues
1613
0
    return RValue::get(CGF.Builder.CreateLoad(addr));
1614
0
  if (LVal.isBitField())
1615
0
    return CGF.EmitLoadOfBitfieldLValue(
1616
0
        LValue::MakeBitfield(addr, LVal.getBitFieldInfo(), LVal.getType(),
1617
0
                             LVal.getBaseInfo(), TBAAAccessInfo()), loc);
1618
0
  if (LVal.isVectorElt())
1619
0
    return CGF.EmitLoadOfLValue(
1620
0
        LValue::MakeVectorElt(addr, LVal.getVectorIdx(), LVal.getType(),
1621
0
                              LVal.getBaseInfo(), TBAAAccessInfo()), loc);
1622
0
  assert(LVal.isExtVectorElt());
1623
0
  return CGF.EmitLoadOfExtVectorElementLValue(LValue::MakeExtVectorElt(
1624
0
      addr, LVal.getExtVectorElts(), LVal.getType(),
1625
0
      LVal.getBaseInfo(), TBAAAccessInfo()));
1626
0
}
1627
1628
RValue AtomicInfo::ConvertIntToValueOrAtomic(llvm::Value *IntVal,
1629
                                             AggValueSlot ResultSlot,
1630
                                             SourceLocation Loc,
1631
0
                                             bool AsValue) const {
1632
  // Try not to in some easy cases.
1633
0
  assert(IntVal->getType()->isIntegerTy() && "Expected integer value");
1634
0
  if (getEvaluationKind() == TEK_Scalar &&
1635
0
      (((!LVal.isBitField() ||
1636
0
         LVal.getBitFieldInfo().Size == ValueSizeInBits) &&
1637
0
        !hasPadding()) ||
1638
0
       !AsValue)) {
1639
0
    auto *ValTy = AsValue
1640
0
                      ? CGF.ConvertTypeForMem(ValueTy)
1641
0
                      : getAtomicAddress().getElementType();
1642
0
    if (ValTy->isIntegerTy()) {
1643
0
      assert(IntVal->getType() == ValTy && "Different integer types.");
1644
0
      return RValue::get(CGF.EmitFromMemory(IntVal, ValueTy));
1645
0
    } else if (ValTy->isPointerTy())
1646
0
      return RValue::get(CGF.Builder.CreateIntToPtr(IntVal, ValTy));
1647
0
    else if (llvm::CastInst::isBitCastable(IntVal->getType(), ValTy))
1648
0
      return RValue::get(CGF.Builder.CreateBitCast(IntVal, ValTy));
1649
0
  }
1650
1651
  // Create a temporary.  This needs to be big enough to hold the
1652
  // atomic integer.
1653
0
  Address Temp = Address::invalid();
1654
0
  bool TempIsVolatile = false;
1655
0
  if (AsValue && getEvaluationKind() == TEK_Aggregate) {
1656
0
    assert(!ResultSlot.isIgnored());
1657
0
    Temp = ResultSlot.getAddress();
1658
0
    TempIsVolatile = ResultSlot.isVolatile();
1659
0
  } else {
1660
0
    Temp = CreateTempAlloca();
1661
0
  }
1662
1663
  // Slam the integer into the temporary.
1664
0
  Address CastTemp = castToAtomicIntPointer(Temp);
1665
0
  CGF.Builder.CreateStore(IntVal, CastTemp)
1666
0
      ->setVolatile(TempIsVolatile);
1667
1668
0
  return convertAtomicTempToRValue(Temp, ResultSlot, Loc, AsValue);
1669
0
}
1670
1671
void AtomicInfo::EmitAtomicLoadLibcall(llvm::Value *AddForLoaded,
1672
0
                                       llvm::AtomicOrdering AO, bool) {
1673
  // void __atomic_load(size_t size, void *mem, void *return, int order);
1674
0
  CallArgList Args;
1675
0
  Args.add(RValue::get(getAtomicSizeValue()), CGF.getContext().getSizeType());
1676
0
  Args.add(RValue::get(getAtomicPointer()), CGF.getContext().VoidPtrTy);
1677
0
  Args.add(RValue::get(AddForLoaded), CGF.getContext().VoidPtrTy);
1678
0
  Args.add(
1679
0
      RValue::get(llvm::ConstantInt::get(CGF.IntTy, (int)llvm::toCABI(AO))),
1680
0
      CGF.getContext().IntTy);
1681
0
  emitAtomicLibcall(CGF, "__atomic_load", CGF.getContext().VoidTy, Args);
1682
0
}
1683
1684
llvm::Value *AtomicInfo::EmitAtomicLoadOp(llvm::AtomicOrdering AO,
1685
0
                                          bool IsVolatile) {
1686
  // Okay, we're doing this natively.
1687
0
  Address Addr = getAtomicAddressAsAtomicIntPointer();
1688
0
  llvm::LoadInst *Load = CGF.Builder.CreateLoad(Addr, "atomic-load");
1689
0
  Load->setAtomic(AO);
1690
1691
  // Other decoration.
1692
0
  if (IsVolatile)
1693
0
    Load->setVolatile(true);
1694
0
  CGF.CGM.DecorateInstructionWithTBAA(Load, LVal.getTBAAInfo());
1695
0
  return Load;
1696
0
}
1697
1698
/// An LValue is a candidate for having its loads and stores be made atomic if
1699
/// we are operating under /volatile:ms *and* the LValue itself is volatile and
1700
/// performing such an operation can be performed without a libcall.
1701
0
bool CodeGenFunction::LValueIsSuitableForInlineAtomic(LValue LV) {
1702
0
  if (!CGM.getLangOpts().MSVolatile) return false;
1703
0
  AtomicInfo AI(*this, LV);
1704
0
  bool IsVolatile = LV.isVolatile() || hasVolatileMember(LV.getType());
1705
  // An atomic is inline if we don't need to use a libcall.
1706
0
  bool AtomicIsInline = !AI.shouldUseLibcall();
1707
  // MSVC doesn't seem to do this for types wider than a pointer.
1708
0
  if (getContext().getTypeSize(LV.getType()) >
1709
0
      getContext().getTypeSize(getContext().getIntPtrType()))
1710
0
    return false;
1711
0
  return IsVolatile && AtomicIsInline;
1712
0
}
1713
1714
RValue CodeGenFunction::EmitAtomicLoad(LValue LV, SourceLocation SL,
1715
0
                                       AggValueSlot Slot) {
1716
0
  llvm::AtomicOrdering AO;
1717
0
  bool IsVolatile = LV.isVolatileQualified();
1718
0
  if (LV.getType()->isAtomicType()) {
1719
0
    AO = llvm::AtomicOrdering::SequentiallyConsistent;
1720
0
  } else {
1721
0
    AO = llvm::AtomicOrdering::Acquire;
1722
0
    IsVolatile = true;
1723
0
  }
1724
0
  return EmitAtomicLoad(LV, SL, AO, IsVolatile, Slot);
1725
0
}
1726
1727
RValue AtomicInfo::EmitAtomicLoad(AggValueSlot ResultSlot, SourceLocation Loc,
1728
                                  bool AsValue, llvm::AtomicOrdering AO,
1729
0
                                  bool IsVolatile) {
1730
  // Check whether we should use a library call.
1731
0
  if (shouldUseLibcall()) {
1732
0
    Address TempAddr = Address::invalid();
1733
0
    if (LVal.isSimple() && !ResultSlot.isIgnored()) {
1734
0
      assert(getEvaluationKind() == TEK_Aggregate);
1735
0
      TempAddr = ResultSlot.getAddress();
1736
0
    } else
1737
0
      TempAddr = CreateTempAlloca();
1738
1739
0
    EmitAtomicLoadLibcall(TempAddr.getPointer(), AO, IsVolatile);
1740
1741
    // Okay, turn that back into the original value or whole atomic (for
1742
    // non-simple lvalues) type.
1743
0
    return convertAtomicTempToRValue(TempAddr, ResultSlot, Loc, AsValue);
1744
0
  }
1745
1746
  // Okay, we're doing this natively.
1747
0
  auto *Load = EmitAtomicLoadOp(AO, IsVolatile);
1748
1749
  // If we're ignoring an aggregate return, don't do anything.
1750
0
  if (getEvaluationKind() == TEK_Aggregate && ResultSlot.isIgnored())
1751
0
    return RValue::getAggregate(Address::invalid(), false);
1752
1753
  // Okay, turn that back into the original value or atomic (for non-simple
1754
  // lvalues) type.
1755
0
  return ConvertIntToValueOrAtomic(Load, ResultSlot, Loc, AsValue);
1756
0
}
1757
1758
/// Emit a load from an l-value of atomic type.  Note that the r-value
1759
/// we produce is an r-value of the atomic *value* type.
1760
RValue CodeGenFunction::EmitAtomicLoad(LValue src, SourceLocation loc,
1761
                                       llvm::AtomicOrdering AO, bool IsVolatile,
1762
0
                                       AggValueSlot resultSlot) {
1763
0
  AtomicInfo Atomics(*this, src);
1764
0
  return Atomics.EmitAtomicLoad(resultSlot, loc, /*AsValue=*/true, AO,
1765
0
                                IsVolatile);
1766
0
}
1767
1768
/// Copy an r-value into memory as part of storing to an atomic type.
1769
/// This needs to create a bit-pattern suitable for atomic operations.
1770
0
void AtomicInfo::emitCopyIntoMemory(RValue rvalue) const {
1771
0
  assert(LVal.isSimple());
1772
  // If we have an r-value, the rvalue should be of the atomic type,
1773
  // which means that the caller is responsible for having zeroed
1774
  // any padding.  Just do an aggregate copy of that type.
1775
0
  if (rvalue.isAggregate()) {
1776
0
    LValue Dest = CGF.MakeAddrLValue(getAtomicAddress(), getAtomicType());
1777
0
    LValue Src = CGF.MakeAddrLValue(rvalue.getAggregateAddress(),
1778
0
                                    getAtomicType());
1779
0
    bool IsVolatile = rvalue.isVolatileQualified() ||
1780
0
                      LVal.isVolatileQualified();
1781
0
    CGF.EmitAggregateCopy(Dest, Src, getAtomicType(),
1782
0
                          AggValueSlot::DoesNotOverlap, IsVolatile);
1783
0
    return;
1784
0
  }
1785
1786
  // Okay, otherwise we're copying stuff.
1787
1788
  // Zero out the buffer if necessary.
1789
0
  emitMemSetZeroIfNecessary();
1790
1791
  // Drill past the padding if present.
1792
0
  LValue TempLVal = projectValue();
1793
1794
  // Okay, store the rvalue in.
1795
0
  if (rvalue.isScalar()) {
1796
0
    CGF.EmitStoreOfScalar(rvalue.getScalarVal(), TempLVal, /*init*/ true);
1797
0
  } else {
1798
0
    CGF.EmitStoreOfComplex(rvalue.getComplexVal(), TempLVal, /*init*/ true);
1799
0
  }
1800
0
}
1801
1802
1803
/// Materialize an r-value into memory for the purposes of storing it
1804
/// to an atomic type.
1805
0
Address AtomicInfo::materializeRValue(RValue rvalue) const {
1806
  // Aggregate r-values are already in memory, and EmitAtomicStore
1807
  // requires them to be values of the atomic type.
1808
0
  if (rvalue.isAggregate())
1809
0
    return rvalue.getAggregateAddress();
1810
1811
  // Otherwise, make a temporary and materialize into it.
1812
0
  LValue TempLV = CGF.MakeAddrLValue(CreateTempAlloca(), getAtomicType());
1813
0
  AtomicInfo Atomics(CGF, TempLV);
1814
0
  Atomics.emitCopyIntoMemory(rvalue);
1815
0
  return TempLV.getAddress(CGF);
1816
0
}
1817
1818
0
llvm::Value *AtomicInfo::convertRValueToInt(RValue RVal) const {
1819
  // If we've got a scalar value of the right size, try to avoid going
1820
  // through memory.
1821
0
  if (RVal.isScalar() && (!hasPadding() || !LVal.isSimple())) {
1822
0
    llvm::Value *Value = RVal.getScalarVal();
1823
0
    if (isa<llvm::IntegerType>(Value->getType()))
1824
0
      return CGF.EmitToMemory(Value, ValueTy);
1825
0
    else {
1826
0
      llvm::IntegerType *InputIntTy = llvm::IntegerType::get(
1827
0
          CGF.getLLVMContext(),
1828
0
          LVal.isSimple() ? getValueSizeInBits() : getAtomicSizeInBits());
1829
0
      if (isa<llvm::PointerType>(Value->getType()))
1830
0
        return CGF.Builder.CreatePtrToInt(Value, InputIntTy);
1831
0
      else if (llvm::BitCastInst::isBitCastable(Value->getType(), InputIntTy))
1832
0
        return CGF.Builder.CreateBitCast(Value, InputIntTy);
1833
0
    }
1834
0
  }
1835
  // Otherwise, we need to go through memory.
1836
  // Put the r-value in memory.
1837
0
  Address Addr = materializeRValue(RVal);
1838
1839
  // Cast the temporary to the atomic int type and pull a value out.
1840
0
  Addr = castToAtomicIntPointer(Addr);
1841
0
  return CGF.Builder.CreateLoad(Addr);
1842
0
}
1843
1844
std::pair<llvm::Value *, llvm::Value *> AtomicInfo::EmitAtomicCompareExchangeOp(
1845
    llvm::Value *ExpectedVal, llvm::Value *DesiredVal,
1846
0
    llvm::AtomicOrdering Success, llvm::AtomicOrdering Failure, bool IsWeak) {
1847
  // Do the atomic store.
1848
0
  Address Addr = getAtomicAddressAsAtomicIntPointer();
1849
0
  auto *Inst = CGF.Builder.CreateAtomicCmpXchg(Addr, ExpectedVal, DesiredVal,
1850
0
                                               Success, Failure);
1851
  // Other decoration.
1852
0
  Inst->setVolatile(LVal.isVolatileQualified());
1853
0
  Inst->setWeak(IsWeak);
1854
1855
  // Okay, turn that back into the original value type.
1856
0
  auto *PreviousVal = CGF.Builder.CreateExtractValue(Inst, /*Idxs=*/0);
1857
0
  auto *SuccessFailureVal = CGF.Builder.CreateExtractValue(Inst, /*Idxs=*/1);
1858
0
  return std::make_pair(PreviousVal, SuccessFailureVal);
1859
0
}
1860
1861
llvm::Value *
1862
AtomicInfo::EmitAtomicCompareExchangeLibcall(llvm::Value *ExpectedAddr,
1863
                                             llvm::Value *DesiredAddr,
1864
                                             llvm::AtomicOrdering Success,
1865
0
                                             llvm::AtomicOrdering Failure) {
1866
  // bool __atomic_compare_exchange(size_t size, void *obj, void *expected,
1867
  // void *desired, int success, int failure);
1868
0
  CallArgList Args;
1869
0
  Args.add(RValue::get(getAtomicSizeValue()), CGF.getContext().getSizeType());
1870
0
  Args.add(RValue::get(getAtomicPointer()), CGF.getContext().VoidPtrTy);
1871
0
  Args.add(RValue::get(ExpectedAddr), CGF.getContext().VoidPtrTy);
1872
0
  Args.add(RValue::get(DesiredAddr), CGF.getContext().VoidPtrTy);
1873
0
  Args.add(RValue::get(
1874
0
               llvm::ConstantInt::get(CGF.IntTy, (int)llvm::toCABI(Success))),
1875
0
           CGF.getContext().IntTy);
1876
0
  Args.add(RValue::get(
1877
0
               llvm::ConstantInt::get(CGF.IntTy, (int)llvm::toCABI(Failure))),
1878
0
           CGF.getContext().IntTy);
1879
0
  auto SuccessFailureRVal = emitAtomicLibcall(CGF, "__atomic_compare_exchange",
1880
0
                                              CGF.getContext().BoolTy, Args);
1881
1882
0
  return SuccessFailureRVal.getScalarVal();
1883
0
}
1884
1885
std::pair<RValue, llvm::Value *> AtomicInfo::EmitAtomicCompareExchange(
1886
    RValue Expected, RValue Desired, llvm::AtomicOrdering Success,
1887
0
    llvm::AtomicOrdering Failure, bool IsWeak) {
1888
  // Check whether we should use a library call.
1889
0
  if (shouldUseLibcall()) {
1890
    // Produce a source address.
1891
0
    Address ExpectedAddr = materializeRValue(Expected);
1892
0
    Address DesiredAddr = materializeRValue(Desired);
1893
0
    auto *Res = EmitAtomicCompareExchangeLibcall(ExpectedAddr.getPointer(),
1894
0
                                                 DesiredAddr.getPointer(),
1895
0
                                                 Success, Failure);
1896
0
    return std::make_pair(
1897
0
        convertAtomicTempToRValue(ExpectedAddr, AggValueSlot::ignored(),
1898
0
                                  SourceLocation(), /*AsValue=*/false),
1899
0
        Res);
1900
0
  }
1901
1902
  // If we've got a scalar value of the right size, try to avoid going
1903
  // through memory.
1904
0
  auto *ExpectedVal = convertRValueToInt(Expected);
1905
0
  auto *DesiredVal = convertRValueToInt(Desired);
1906
0
  auto Res = EmitAtomicCompareExchangeOp(ExpectedVal, DesiredVal, Success,
1907
0
                                         Failure, IsWeak);
1908
0
  return std::make_pair(
1909
0
      ConvertIntToValueOrAtomic(Res.first, AggValueSlot::ignored(),
1910
0
                                SourceLocation(), /*AsValue=*/false),
1911
0
      Res.second);
1912
0
}
1913
1914
static void
1915
EmitAtomicUpdateValue(CodeGenFunction &CGF, AtomicInfo &Atomics, RValue OldRVal,
1916
                      const llvm::function_ref<RValue(RValue)> &UpdateOp,
1917
0
                      Address DesiredAddr) {
1918
0
  RValue UpRVal;
1919
0
  LValue AtomicLVal = Atomics.getAtomicLValue();
1920
0
  LValue DesiredLVal;
1921
0
  if (AtomicLVal.isSimple()) {
1922
0
    UpRVal = OldRVal;
1923
0
    DesiredLVal = CGF.MakeAddrLValue(DesiredAddr, AtomicLVal.getType());
1924
0
  } else {
1925
    // Build new lvalue for temp address.
1926
0
    Address Ptr = Atomics.materializeRValue(OldRVal);
1927
0
    LValue UpdateLVal;
1928
0
    if (AtomicLVal.isBitField()) {
1929
0
      UpdateLVal =
1930
0
          LValue::MakeBitfield(Ptr, AtomicLVal.getBitFieldInfo(),
1931
0
                               AtomicLVal.getType(),
1932
0
                               AtomicLVal.getBaseInfo(),
1933
0
                               AtomicLVal.getTBAAInfo());
1934
0
      DesiredLVal =
1935
0
          LValue::MakeBitfield(DesiredAddr, AtomicLVal.getBitFieldInfo(),
1936
0
                               AtomicLVal.getType(), AtomicLVal.getBaseInfo(),
1937
0
                               AtomicLVal.getTBAAInfo());
1938
0
    } else if (AtomicLVal.isVectorElt()) {
1939
0
      UpdateLVal = LValue::MakeVectorElt(Ptr, AtomicLVal.getVectorIdx(),
1940
0
                                         AtomicLVal.getType(),
1941
0
                                         AtomicLVal.getBaseInfo(),
1942
0
                                         AtomicLVal.getTBAAInfo());
1943
0
      DesiredLVal = LValue::MakeVectorElt(
1944
0
          DesiredAddr, AtomicLVal.getVectorIdx(), AtomicLVal.getType(),
1945
0
          AtomicLVal.getBaseInfo(), AtomicLVal.getTBAAInfo());
1946
0
    } else {
1947
0
      assert(AtomicLVal.isExtVectorElt());
1948
0
      UpdateLVal = LValue::MakeExtVectorElt(Ptr, AtomicLVal.getExtVectorElts(),
1949
0
                                            AtomicLVal.getType(),
1950
0
                                            AtomicLVal.getBaseInfo(),
1951
0
                                            AtomicLVal.getTBAAInfo());
1952
0
      DesiredLVal = LValue::MakeExtVectorElt(
1953
0
          DesiredAddr, AtomicLVal.getExtVectorElts(), AtomicLVal.getType(),
1954
0
          AtomicLVal.getBaseInfo(), AtomicLVal.getTBAAInfo());
1955
0
    }
1956
0
    UpRVal = CGF.EmitLoadOfLValue(UpdateLVal, SourceLocation());
1957
0
  }
1958
  // Store new value in the corresponding memory area.
1959
0
  RValue NewRVal = UpdateOp(UpRVal);
1960
0
  if (NewRVal.isScalar()) {
1961
0
    CGF.EmitStoreThroughLValue(NewRVal, DesiredLVal);
1962
0
  } else {
1963
0
    assert(NewRVal.isComplex());
1964
0
    CGF.EmitStoreOfComplex(NewRVal.getComplexVal(), DesiredLVal,
1965
0
                           /*isInit=*/false);
1966
0
  }
1967
0
}
1968
1969
void AtomicInfo::EmitAtomicUpdateLibcall(
1970
    llvm::AtomicOrdering AO, const llvm::function_ref<RValue(RValue)> &UpdateOp,
1971
0
    bool IsVolatile) {
1972
0
  auto Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO);
1973
1974
0
  Address ExpectedAddr = CreateTempAlloca();
1975
1976
0
  EmitAtomicLoadLibcall(ExpectedAddr.getPointer(), AO, IsVolatile);
1977
0
  auto *ContBB = CGF.createBasicBlock("atomic_cont");
1978
0
  auto *ExitBB = CGF.createBasicBlock("atomic_exit");
1979
0
  CGF.EmitBlock(ContBB);
1980
0
  Address DesiredAddr = CreateTempAlloca();
1981
0
  if ((LVal.isBitField() && BFI.Size != ValueSizeInBits) ||
1982
0
      requiresMemSetZero(getAtomicAddress().getElementType())) {
1983
0
    auto *OldVal = CGF.Builder.CreateLoad(ExpectedAddr);
1984
0
    CGF.Builder.CreateStore(OldVal, DesiredAddr);
1985
0
  }
1986
0
  auto OldRVal = convertAtomicTempToRValue(ExpectedAddr,
1987
0
                                           AggValueSlot::ignored(),
1988
0
                                           SourceLocation(), /*AsValue=*/false);
1989
0
  EmitAtomicUpdateValue(CGF, *this, OldRVal, UpdateOp, DesiredAddr);
1990
0
  auto *Res =
1991
0
      EmitAtomicCompareExchangeLibcall(ExpectedAddr.getPointer(),
1992
0
                                       DesiredAddr.getPointer(),
1993
0
                                       AO, Failure);
1994
0
  CGF.Builder.CreateCondBr(Res, ExitBB, ContBB);
1995
0
  CGF.EmitBlock(ExitBB, /*IsFinished=*/true);
1996
0
}
1997
1998
void AtomicInfo::EmitAtomicUpdateOp(
1999
    llvm::AtomicOrdering AO, const llvm::function_ref<RValue(RValue)> &UpdateOp,
2000
0
    bool IsVolatile) {
2001
0
  auto Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO);
2002
2003
  // Do the atomic load.
2004
0
  auto *OldVal = EmitAtomicLoadOp(Failure, IsVolatile);
2005
  // For non-simple lvalues perform compare-and-swap procedure.
2006
0
  auto *ContBB = CGF.createBasicBlock("atomic_cont");
2007
0
  auto *ExitBB = CGF.createBasicBlock("atomic_exit");
2008
0
  auto *CurBB = CGF.Builder.GetInsertBlock();
2009
0
  CGF.EmitBlock(ContBB);
2010
0
  llvm::PHINode *PHI = CGF.Builder.CreatePHI(OldVal->getType(),
2011
0
                                             /*NumReservedValues=*/2);
2012
0
  PHI->addIncoming(OldVal, CurBB);
2013
0
  Address NewAtomicAddr = CreateTempAlloca();
2014
0
  Address NewAtomicIntAddr = castToAtomicIntPointer(NewAtomicAddr);
2015
0
  if ((LVal.isBitField() && BFI.Size != ValueSizeInBits) ||
2016
0
      requiresMemSetZero(getAtomicAddress().getElementType())) {
2017
0
    CGF.Builder.CreateStore(PHI, NewAtomicIntAddr);
2018
0
  }
2019
0
  auto OldRVal = ConvertIntToValueOrAtomic(PHI, AggValueSlot::ignored(),
2020
0
                                           SourceLocation(), /*AsValue=*/false);
2021
0
  EmitAtomicUpdateValue(CGF, *this, OldRVal, UpdateOp, NewAtomicAddr);
2022
0
  auto *DesiredVal = CGF.Builder.CreateLoad(NewAtomicIntAddr);
2023
  // Try to write new value using cmpxchg operation.
2024
0
  auto Res = EmitAtomicCompareExchangeOp(PHI, DesiredVal, AO, Failure);
2025
0
  PHI->addIncoming(Res.first, CGF.Builder.GetInsertBlock());
2026
0
  CGF.Builder.CreateCondBr(Res.second, ExitBB, ContBB);
2027
0
  CGF.EmitBlock(ExitBB, /*IsFinished=*/true);
2028
0
}
2029
2030
static void EmitAtomicUpdateValue(CodeGenFunction &CGF, AtomicInfo &Atomics,
2031
0
                                  RValue UpdateRVal, Address DesiredAddr) {
2032
0
  LValue AtomicLVal = Atomics.getAtomicLValue();
2033
0
  LValue DesiredLVal;
2034
  // Build new lvalue for temp address.
2035
0
  if (AtomicLVal.isBitField()) {
2036
0
    DesiredLVal =
2037
0
        LValue::MakeBitfield(DesiredAddr, AtomicLVal.getBitFieldInfo(),
2038
0
                             AtomicLVal.getType(), AtomicLVal.getBaseInfo(),
2039
0
                             AtomicLVal.getTBAAInfo());
2040
0
  } else if (AtomicLVal.isVectorElt()) {
2041
0
    DesiredLVal =
2042
0
        LValue::MakeVectorElt(DesiredAddr, AtomicLVal.getVectorIdx(),
2043
0
                              AtomicLVal.getType(), AtomicLVal.getBaseInfo(),
2044
0
                              AtomicLVal.getTBAAInfo());
2045
0
  } else {
2046
0
    assert(AtomicLVal.isExtVectorElt());
2047
0
    DesiredLVal = LValue::MakeExtVectorElt(
2048
0
        DesiredAddr, AtomicLVal.getExtVectorElts(), AtomicLVal.getType(),
2049
0
        AtomicLVal.getBaseInfo(), AtomicLVal.getTBAAInfo());
2050
0
  }
2051
  // Store new value in the corresponding memory area.
2052
0
  assert(UpdateRVal.isScalar());
2053
0
  CGF.EmitStoreThroughLValue(UpdateRVal, DesiredLVal);
2054
0
}
2055
2056
void AtomicInfo::EmitAtomicUpdateLibcall(llvm::AtomicOrdering AO,
2057
0
                                         RValue UpdateRVal, bool IsVolatile) {
2058
0
  auto Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO);
2059
2060
0
  Address ExpectedAddr = CreateTempAlloca();
2061
2062
0
  EmitAtomicLoadLibcall(ExpectedAddr.getPointer(), AO, IsVolatile);
2063
0
  auto *ContBB = CGF.createBasicBlock("atomic_cont");
2064
0
  auto *ExitBB = CGF.createBasicBlock("atomic_exit");
2065
0
  CGF.EmitBlock(ContBB);
2066
0
  Address DesiredAddr = CreateTempAlloca();
2067
0
  if ((LVal.isBitField() && BFI.Size != ValueSizeInBits) ||
2068
0
      requiresMemSetZero(getAtomicAddress().getElementType())) {
2069
0
    auto *OldVal = CGF.Builder.CreateLoad(ExpectedAddr);
2070
0
    CGF.Builder.CreateStore(OldVal, DesiredAddr);
2071
0
  }
2072
0
  EmitAtomicUpdateValue(CGF, *this, UpdateRVal, DesiredAddr);
2073
0
  auto *Res =
2074
0
      EmitAtomicCompareExchangeLibcall(ExpectedAddr.getPointer(),
2075
0
                                       DesiredAddr.getPointer(),
2076
0
                                       AO, Failure);
2077
0
  CGF.Builder.CreateCondBr(Res, ExitBB, ContBB);
2078
0
  CGF.EmitBlock(ExitBB, /*IsFinished=*/true);
2079
0
}
2080
2081
void AtomicInfo::EmitAtomicUpdateOp(llvm::AtomicOrdering AO, RValue UpdateRVal,
2082
0
                                    bool IsVolatile) {
2083
0
  auto Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO);
2084
2085
  // Do the atomic load.
2086
0
  auto *OldVal = EmitAtomicLoadOp(Failure, IsVolatile);
2087
  // For non-simple lvalues perform compare-and-swap procedure.
2088
0
  auto *ContBB = CGF.createBasicBlock("atomic_cont");
2089
0
  auto *ExitBB = CGF.createBasicBlock("atomic_exit");
2090
0
  auto *CurBB = CGF.Builder.GetInsertBlock();
2091
0
  CGF.EmitBlock(ContBB);
2092
0
  llvm::PHINode *PHI = CGF.Builder.CreatePHI(OldVal->getType(),
2093
0
                                             /*NumReservedValues=*/2);
2094
0
  PHI->addIncoming(OldVal, CurBB);
2095
0
  Address NewAtomicAddr = CreateTempAlloca();
2096
0
  Address NewAtomicIntAddr = castToAtomicIntPointer(NewAtomicAddr);
2097
0
  if ((LVal.isBitField() && BFI.Size != ValueSizeInBits) ||
2098
0
      requiresMemSetZero(getAtomicAddress().getElementType())) {
2099
0
    CGF.Builder.CreateStore(PHI, NewAtomicIntAddr);
2100
0
  }
2101
0
  EmitAtomicUpdateValue(CGF, *this, UpdateRVal, NewAtomicAddr);
2102
0
  auto *DesiredVal = CGF.Builder.CreateLoad(NewAtomicIntAddr);
2103
  // Try to write new value using cmpxchg operation.
2104
0
  auto Res = EmitAtomicCompareExchangeOp(PHI, DesiredVal, AO, Failure);
2105
0
  PHI->addIncoming(Res.first, CGF.Builder.GetInsertBlock());
2106
0
  CGF.Builder.CreateCondBr(Res.second, ExitBB, ContBB);
2107
0
  CGF.EmitBlock(ExitBB, /*IsFinished=*/true);
2108
0
}
2109
2110
void AtomicInfo::EmitAtomicUpdate(
2111
    llvm::AtomicOrdering AO, const llvm::function_ref<RValue(RValue)> &UpdateOp,
2112
0
    bool IsVolatile) {
2113
0
  if (shouldUseLibcall()) {
2114
0
    EmitAtomicUpdateLibcall(AO, UpdateOp, IsVolatile);
2115
0
  } else {
2116
0
    EmitAtomicUpdateOp(AO, UpdateOp, IsVolatile);
2117
0
  }
2118
0
}
2119
2120
void AtomicInfo::EmitAtomicUpdate(llvm::AtomicOrdering AO, RValue UpdateRVal,
2121
0
                                  bool IsVolatile) {
2122
0
  if (shouldUseLibcall()) {
2123
0
    EmitAtomicUpdateLibcall(AO, UpdateRVal, IsVolatile);
2124
0
  } else {
2125
0
    EmitAtomicUpdateOp(AO, UpdateRVal, IsVolatile);
2126
0
  }
2127
0
}
2128
2129
void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue lvalue,
2130
0
                                      bool isInit) {
2131
0
  bool IsVolatile = lvalue.isVolatileQualified();
2132
0
  llvm::AtomicOrdering AO;
2133
0
  if (lvalue.getType()->isAtomicType()) {
2134
0
    AO = llvm::AtomicOrdering::SequentiallyConsistent;
2135
0
  } else {
2136
0
    AO = llvm::AtomicOrdering::Release;
2137
0
    IsVolatile = true;
2138
0
  }
2139
0
  return EmitAtomicStore(rvalue, lvalue, AO, IsVolatile, isInit);
2140
0
}
2141
2142
/// Emit a store to an l-value of atomic type.
2143
///
2144
/// Note that the r-value is expected to be an r-value *of the atomic
2145
/// type*; this means that for aggregate r-values, it should include
2146
/// storage for any padding that was necessary.
2147
void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue dest,
2148
                                      llvm::AtomicOrdering AO, bool IsVolatile,
2149
0
                                      bool isInit) {
2150
  // If this is an aggregate r-value, it should agree in type except
2151
  // maybe for address-space qualification.
2152
0
  assert(!rvalue.isAggregate() ||
2153
0
         rvalue.getAggregateAddress().getElementType() ==
2154
0
             dest.getAddress(*this).getElementType());
2155
2156
0
  AtomicInfo atomics(*this, dest);
2157
0
  LValue LVal = atomics.getAtomicLValue();
2158
2159
  // If this is an initialization, just put the value there normally.
2160
0
  if (LVal.isSimple()) {
2161
0
    if (isInit) {
2162
0
      atomics.emitCopyIntoMemory(rvalue);
2163
0
      return;
2164
0
    }
2165
2166
    // Check whether we should use a library call.
2167
0
    if (atomics.shouldUseLibcall()) {
2168
      // Produce a source address.
2169
0
      Address srcAddr = atomics.materializeRValue(rvalue);
2170
2171
      // void __atomic_store(size_t size, void *mem, void *val, int order)
2172
0
      CallArgList args;
2173
0
      args.add(RValue::get(atomics.getAtomicSizeValue()),
2174
0
               getContext().getSizeType());
2175
0
      args.add(RValue::get(atomics.getAtomicPointer()), getContext().VoidPtrTy);
2176
0
      args.add(RValue::get(srcAddr.getPointer()), getContext().VoidPtrTy);
2177
0
      args.add(
2178
0
          RValue::get(llvm::ConstantInt::get(IntTy, (int)llvm::toCABI(AO))),
2179
0
          getContext().IntTy);
2180
0
      emitAtomicLibcall(*this, "__atomic_store", getContext().VoidTy, args);
2181
0
      return;
2182
0
    }
2183
2184
    // Okay, we're doing this natively.
2185
0
    llvm::Value *intValue = atomics.convertRValueToInt(rvalue);
2186
2187
    // Do the atomic store.
2188
0
    Address addr = atomics.castToAtomicIntPointer(atomics.getAtomicAddress());
2189
0
    intValue = Builder.CreateIntCast(
2190
0
        intValue, addr.getElementType(), /*isSigned=*/false);
2191
0
    llvm::StoreInst *store = Builder.CreateStore(intValue, addr);
2192
2193
0
    if (AO == llvm::AtomicOrdering::Acquire)
2194
0
      AO = llvm::AtomicOrdering::Monotonic;
2195
0
    else if (AO == llvm::AtomicOrdering::AcquireRelease)
2196
0
      AO = llvm::AtomicOrdering::Release;
2197
    // Initializations don't need to be atomic.
2198
0
    if (!isInit)
2199
0
      store->setAtomic(AO);
2200
2201
    // Other decoration.
2202
0
    if (IsVolatile)
2203
0
      store->setVolatile(true);
2204
0
    CGM.DecorateInstructionWithTBAA(store, dest.getTBAAInfo());
2205
0
    return;
2206
0
  }
2207
2208
  // Emit simple atomic update operation.
2209
0
  atomics.EmitAtomicUpdate(AO, rvalue, IsVolatile);
2210
0
}
2211
2212
/// Emit a compare-and-exchange op for atomic type.
2213
///
2214
std::pair<RValue, llvm::Value *> CodeGenFunction::EmitAtomicCompareExchange(
2215
    LValue Obj, RValue Expected, RValue Desired, SourceLocation Loc,
2216
    llvm::AtomicOrdering Success, llvm::AtomicOrdering Failure, bool IsWeak,
2217
0
    AggValueSlot Slot) {
2218
  // If this is an aggregate r-value, it should agree in type except
2219
  // maybe for address-space qualification.
2220
0
  assert(!Expected.isAggregate() ||
2221
0
         Expected.getAggregateAddress().getElementType() ==
2222
0
             Obj.getAddress(*this).getElementType());
2223
0
  assert(!Desired.isAggregate() ||
2224
0
         Desired.getAggregateAddress().getElementType() ==
2225
0
             Obj.getAddress(*this).getElementType());
2226
0
  AtomicInfo Atomics(*this, Obj);
2227
2228
0
  return Atomics.EmitAtomicCompareExchange(Expected, Desired, Success, Failure,
2229
0
                                           IsWeak);
2230
0
}
2231
2232
void CodeGenFunction::EmitAtomicUpdate(
2233
    LValue LVal, llvm::AtomicOrdering AO,
2234
0
    const llvm::function_ref<RValue(RValue)> &UpdateOp, bool IsVolatile) {
2235
0
  AtomicInfo Atomics(*this, LVal);
2236
0
  Atomics.EmitAtomicUpdate(AO, UpdateOp, IsVolatile);
2237
0
}
2238
2239
0
void CodeGenFunction::EmitAtomicInit(Expr *init, LValue dest) {
2240
0
  AtomicInfo atomics(*this, dest);
2241
2242
0
  switch (atomics.getEvaluationKind()) {
2243
0
  case TEK_Scalar: {
2244
0
    llvm::Value *value = EmitScalarExpr(init);
2245
0
    atomics.emitCopyIntoMemory(RValue::get(value));
2246
0
    return;
2247
0
  }
2248
2249
0
  case TEK_Complex: {
2250
0
    ComplexPairTy value = EmitComplexExpr(init);
2251
0
    atomics.emitCopyIntoMemory(RValue::getComplex(value));
2252
0
    return;
2253
0
  }
2254
2255
0
  case TEK_Aggregate: {
2256
    // Fix up the destination if the initializer isn't an expression
2257
    // of atomic type.
2258
0
    bool Zeroed = false;
2259
0
    if (!init->getType()->isAtomicType()) {
2260
0
      Zeroed = atomics.emitMemSetZeroIfNecessary();
2261
0
      dest = atomics.projectValue();
2262
0
    }
2263
2264
    // Evaluate the expression directly into the destination.
2265
0
    AggValueSlot slot = AggValueSlot::forLValue(
2266
0
        dest, *this, AggValueSlot::IsNotDestructed,
2267
0
        AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased,
2268
0
        AggValueSlot::DoesNotOverlap,
2269
0
        Zeroed ? AggValueSlot::IsZeroed : AggValueSlot::IsNotZeroed);
2270
2271
0
    EmitAggExpr(init, slot);
2272
0
    return;
2273
0
  }
2274
0
  }
2275
0
  llvm_unreachable("bad evaluation kind");
2276
0
}