@@ -188,8 +188,7 @@ static Value *EmitFromInt(CodeGenFunction &CGF, llvm::Value *V,
188188 return V;
189189}
190190
191- static llvm::Value *CheckAtomicAlignment(CodeGenFunction &CGF,
192- const CallExpr *E) {
191+ static Address CheckAtomicAlignment(CodeGenFunction &CGF, const CallExpr *E) {
193192 ASTContext &Ctx = CGF.getContext();
194193 Address Ptr = CGF.EmitPointerWithAlignment(E->getArg(0));
195194 unsigned Bytes = Ptr.getElementType()->isPointerTy()
@@ -199,8 +198,10 @@ static llvm::Value *CheckAtomicAlignment(CodeGenFunction &CGF,
199198 if (Align % Bytes != 0) {
200199 DiagnosticsEngine &Diags = CGF.CGM.getDiags();
201200 Diags.Report(E->getBeginLoc(), diag::warn_sync_op_misaligned);
201+ // Force address to be at least naturally-aligned.
202+ return Ptr.withAlignment(CharUnits::fromQuantity(Bytes));
202203 }
203- return Ptr.getPointer() ;
204+ return Ptr;
204205}
205206
206207/// Utility to insert an atomic instruction based on Intrinsic::ID
@@ -215,19 +216,17 @@ static Value *MakeBinaryAtomicValue(
215216 E->getArg(0)->getType()->getPointeeType()));
216217 assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType()));
217218
218- llvm::Value *DestPtr = CheckAtomicAlignment(CGF, E);
219+ Address DestAddr = CheckAtomicAlignment(CGF, E);
219220
220221 llvm::IntegerType *IntType = llvm::IntegerType::get(
221222 CGF.getLLVMContext(), CGF.getContext().getTypeSize(T));
222223
223- llvm::Value *Args[2];
224- Args[0] = DestPtr;
225- Args[1] = CGF.EmitScalarExpr(E->getArg(1));
226- llvm::Type *ValueType = Args[1]->getType();
227- Args[1] = EmitToInt(CGF, Args[1], T, IntType);
224+ llvm::Value *Val = CGF.EmitScalarExpr(E->getArg(1));
225+ llvm::Type *ValueType = Val->getType();
226+ Val = EmitToInt(CGF, Val, T, IntType);
228227
229- llvm::Value *Result = CGF.Builder.CreateAtomicRMW(
230- Kind, Args[0], Args[1] , Ordering);
228+ llvm::Value *Result =
229+ CGF.Builder.CreateAtomicRMW( Kind, DestAddr, Val , Ordering);
231230 return EmitFromInt(CGF, Result, T, ValueType);
232231}
233232
@@ -270,20 +269,18 @@ static RValue EmitBinaryAtomicPost(CodeGenFunction &CGF,
270269 E->getArg(0)->getType()->getPointeeType()));
271270 assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType()));
272271
273- llvm::Value *DestPtr = CheckAtomicAlignment(CGF, E);
272+ Address DestAddr = CheckAtomicAlignment(CGF, E);
274273
275274 llvm::IntegerType *IntType = llvm::IntegerType::get(
276275 CGF.getLLVMContext(), CGF.getContext().getTypeSize(T));
277276
278- llvm::Value *Args[2];
279- Args[1] = CGF.EmitScalarExpr(E->getArg(1));
280- llvm::Type *ValueType = Args[1]->getType();
281- Args[1] = EmitToInt(CGF, Args[1], T, IntType);
282- Args[0] = DestPtr;
277+ llvm::Value *Val = CGF.EmitScalarExpr(E->getArg(1));
278+ llvm::Type *ValueType = Val->getType();
279+ Val = EmitToInt(CGF, Val, T, IntType);
283280
284281 llvm::Value *Result = CGF.Builder.CreateAtomicRMW(
285- Kind, Args[0], Args[1] , llvm::AtomicOrdering::SequentiallyConsistent);
286- Result = CGF.Builder.CreateBinOp(Op, Result, Args[1] );
282+ Kind, DestAddr, Val , llvm::AtomicOrdering::SequentiallyConsistent);
283+ Result = CGF.Builder.CreateBinOp(Op, Result, Val );
287284 if (Invert)
288285 Result =
289286 CGF.Builder.CreateBinOp(llvm::Instruction::Xor, Result,
@@ -309,20 +306,18 @@ static RValue EmitBinaryAtomicPost(CodeGenFunction &CGF,
309306static Value *MakeAtomicCmpXchgValue(CodeGenFunction &CGF, const CallExpr *E,
310307 bool ReturnBool) {
311308 QualType T = ReturnBool ? E->getArg(1)->getType() : E->getType();
312- llvm::Value *DestPtr = CheckAtomicAlignment(CGF, E);
309+ Address DestAddr = CheckAtomicAlignment(CGF, E);
313310
314311 llvm::IntegerType *IntType = llvm::IntegerType::get(
315312 CGF.getLLVMContext(), CGF.getContext().getTypeSize(T));
316313
317- Value *Args[3];
318- Args[0] = DestPtr;
319- Args[1] = CGF.EmitScalarExpr(E->getArg(1));
320- llvm::Type *ValueType = Args[1]->getType();
321- Args[1] = EmitToInt(CGF, Args[1], T, IntType);
322- Args[2] = EmitToInt(CGF, CGF.EmitScalarExpr(E->getArg(2)), T, IntType);
314+ Value *Cmp = CGF.EmitScalarExpr(E->getArg(1));
315+ llvm::Type *ValueType = Cmp->getType();
316+ Cmp = EmitToInt(CGF, Cmp, T, IntType);
317+ Value *New = EmitToInt(CGF, CGF.EmitScalarExpr(E->getArg(2)), T, IntType);
323318
324319 Value *Pair = CGF.Builder.CreateAtomicCmpXchg(
325- Args[0], Args[1], Args[2] , llvm::AtomicOrdering::SequentiallyConsistent,
320+ DestAddr, Cmp, New , llvm::AtomicOrdering::SequentiallyConsistent,
326321 llvm::AtomicOrdering::SequentiallyConsistent);
327322 if (ReturnBool)
328323 // Extract boolean success flag and zext it to int.
@@ -358,7 +353,8 @@ Value *EmitAtomicCmpXchgForMSIntrin(CodeGenFunction &CGF, const CallExpr *E,
358353 assert(CGF.getContext().hasSameUnqualifiedType(E->getType(),
359354 E->getArg(2)->getType()));
360355
361- auto *Destination = CGF.EmitScalarExpr(E->getArg(0));
356+ Address DestAddr = CheckAtomicAlignment(CGF, E);
357+
362358 auto *Comparand = CGF.EmitScalarExpr(E->getArg(2));
363359 auto *Exchange = CGF.EmitScalarExpr(E->getArg(1));
364360
@@ -372,8 +368,7 @@ Value *EmitAtomicCmpXchgForMSIntrin(CodeGenFunction &CGF, const CallExpr *E,
372368 // _Interlocked* operations in the future, we will have to remove the volatile
373369 // marker.
374370 auto *Result = CGF.Builder.CreateAtomicCmpXchg(
375- Destination, Comparand, Exchange,
376- SuccessOrdering, FailureOrdering);
371+ DestAddr, Comparand, Exchange, SuccessOrdering, FailureOrdering);
377372 Result->setVolatile(true);
378373 return CGF.Builder.CreateExtractValue(Result, 0);
379374}
@@ -386,29 +381,34 @@ Value *EmitAtomicCmpXchgForMSIntrin(CodeGenFunction &CGF, const CallExpr *E,
386381// __int64 _ExchangeHigh,
387382// __int64 _ExchangeLow,
388383// __int64 * _ComparandResult);
384+ //
385+ // Note that Destination is assumed to be at least 16-byte aligned, despite
386+ // being typed int64.
387+
389388static Value *EmitAtomicCmpXchg128ForMSIntrin(CodeGenFunction &CGF,
390389 const CallExpr *E,
391390 AtomicOrdering SuccessOrdering) {
392391 assert(E->getNumArgs() == 4);
393- llvm::Value *Destination = CGF.EmitScalarExpr(E->getArg(0));
392+ llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0));
394393 llvm::Value *ExchangeHigh = CGF.EmitScalarExpr(E->getArg(1));
395394 llvm::Value *ExchangeLow = CGF.EmitScalarExpr(E->getArg(2));
396- llvm::Value *ComparandPtr = CGF.EmitScalarExpr (E->getArg(3));
395+ Address ComparandAddr = CGF.EmitPointerWithAlignment (E->getArg(3));
397396
398- assert(Destination ->getType()->isPointerTy());
397+ assert(DestPtr ->getType()->isPointerTy());
399398 assert(!ExchangeHigh->getType()->isPointerTy());
400399 assert(!ExchangeLow->getType()->isPointerTy());
401- assert(ComparandPtr->getType()->isPointerTy());
402400
403401 // For Release ordering, the failure ordering should be Monotonic.
404402 auto FailureOrdering = SuccessOrdering == AtomicOrdering::Release
405403 ? AtomicOrdering::Monotonic
406404 : SuccessOrdering;
407405
408- // Convert to i128 pointers and values.
406+ // Convert to i128 pointers and values. Alignment is also overridden for
407+ // destination pointer.
409408 llvm::Type *Int128Ty = llvm::IntegerType::get(CGF.getLLVMContext(), 128);
410- Address ComparandResult(ComparandPtr, Int128Ty,
411- CGF.getContext().toCharUnitsFromBits(128));
409+ Address DestAddr(DestPtr, Int128Ty,
410+ CGF.getContext().toCharUnitsFromBits(128));
411+ ComparandAddr = ComparandAddr.withElementType(Int128Ty);
412412
413413 // (((i128)hi) << 64) | ((i128)lo)
414414 ExchangeHigh = CGF.Builder.CreateZExt(ExchangeHigh, Int128Ty);
@@ -418,9 +418,9 @@ static Value *EmitAtomicCmpXchg128ForMSIntrin(CodeGenFunction &CGF,
418418 llvm::Value *Exchange = CGF.Builder.CreateOr(ExchangeHigh, ExchangeLow);
419419
420420 // Load the comparand for the instruction.
421- llvm::Value *Comparand = CGF.Builder.CreateLoad(ComparandResult );
421+ llvm::Value *Comparand = CGF.Builder.CreateLoad(ComparandAddr );
422422
423- auto *CXI = CGF.Builder.CreateAtomicCmpXchg(Destination , Comparand, Exchange,
423+ auto *CXI = CGF.Builder.CreateAtomicCmpXchg(DestAddr , Comparand, Exchange,
424424 SuccessOrdering, FailureOrdering);
425425
426426 // The atomic instruction is marked volatile for consistency with MSVC. This
@@ -431,7 +431,7 @@ static Value *EmitAtomicCmpXchg128ForMSIntrin(CodeGenFunction &CGF,
431431
432432 // Store the result as an outparameter.
433433 CGF.Builder.CreateStore(CGF.Builder.CreateExtractValue(CXI, 0),
434- ComparandResult );
434+ ComparandAddr );
435435
436436 // Get the success boolean and zero extend it to i8.
437437 Value *Success = CGF.Builder.CreateExtractValue(CXI, 1);
@@ -443,24 +443,21 @@ static Value *EmitAtomicIncrementValue(CodeGenFunction &CGF, const CallExpr *E,
443443 assert(E->getArg(0)->getType()->isPointerType());
444444
445445 auto *IntTy = CGF.ConvertType(E->getType());
446+ Address DestAddr = CheckAtomicAlignment(CGF, E);
446447 auto *Result = CGF.Builder.CreateAtomicRMW(
447- AtomicRMWInst::Add,
448- CGF.EmitScalarExpr(E->getArg(0)),
449- ConstantInt::get(IntTy, 1),
450- Ordering);
448+ AtomicRMWInst::Add, DestAddr, ConstantInt::get(IntTy, 1), Ordering);
451449 return CGF.Builder.CreateAdd(Result, ConstantInt::get(IntTy, 1));
452450}
453451
454- static Value *EmitAtomicDecrementValue(CodeGenFunction &CGF, const CallExpr *E,
452+ static Value *EmitAtomicDecrementValue(
453+ CodeGenFunction &CGF, const CallExpr *E,
455454 AtomicOrdering Ordering = AtomicOrdering::SequentiallyConsistent) {
456455 assert(E->getArg(0)->getType()->isPointerType());
457456
458457 auto *IntTy = CGF.ConvertType(E->getType());
458+ Address DestAddr = CheckAtomicAlignment(CGF, E);
459459 auto *Result = CGF.Builder.CreateAtomicRMW(
460- AtomicRMWInst::Sub,
461- CGF.EmitScalarExpr(E->getArg(0)),
462- ConstantInt::get(IntTy, 1),
463- Ordering);
460+ AtomicRMWInst::Sub, DestAddr, ConstantInt::get(IntTy, 1), Ordering);
464461 return CGF.Builder.CreateSub(Result, ConstantInt::get(IntTy, 1));
465462}
466463
@@ -1215,8 +1212,7 @@ static llvm::Value *EmitBitTestIntrinsic(CodeGenFunction &CGF,
12151212 Mask = CGF.Builder.CreateNot(Mask);
12161213 RMWOp = llvm::AtomicRMWInst::And;
12171214 }
1218- OldByte = CGF.Builder.CreateAtomicRMW(RMWOp, ByteAddr.getPointer(), Mask,
1219- Ordering);
1215+ OldByte = CGF.Builder.CreateAtomicRMW(RMWOp, ByteAddr, Mask, Ordering);
12201216 } else {
12211217 // Emit a plain load for the non-interlocked intrinsics.
12221218 OldByte = CGF.Builder.CreateLoad(ByteAddr, "bittest.byte");
@@ -4456,14 +4452,13 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
44564452 case Builtin::BI__sync_lock_release_4:
44574453 case Builtin::BI__sync_lock_release_8:
44584454 case Builtin::BI__sync_lock_release_16: {
4459- Value * Ptr = CheckAtomicAlignment(*this, E);
4455+ Address Ptr = CheckAtomicAlignment(*this, E);
44604456 QualType ElTy = E->getArg(0)->getType()->getPointeeType();
4461- CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy);
4462- llvm::Type *ITy =
4463- llvm::IntegerType::get(getLLVMContext(), StoreSize.getQuantity() * 8 );
4457+
4458+ llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(),
4459+ getContext().getTypeSize(ElTy) );
44644460 llvm::StoreInst *Store =
4465- Builder.CreateAlignedStore(llvm::Constant::getNullValue(ITy), Ptr,
4466- StoreSize);
4461+ Builder.CreateStore(llvm::Constant::getNullValue(ITy), Ptr);
44674462 Store->setAtomic(llvm::AtomicOrdering::Release);
44684463 return RValue::get(nullptr);
44694464 }
@@ -4514,7 +4509,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
45144509 bool Volatile =
45154510 PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified();
45164511
4517- Value *Ptr = EmitScalarExpr(E->getArg(0));
4512+ Address Ptr =
4513+ EmitPointerWithAlignment(E->getArg(0)).withElementType(Int8Ty);
4514+
45184515 Value *NewVal = Builder.getInt8(1);
45194516 Value *Order = EmitScalarExpr(E->getArg(1));
45204517 if (isa<llvm::ConstantInt>(Order)) {
@@ -5035,7 +5032,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
50355032 llvm::IntegerType *IntType = IntegerType::get(
50365033 getLLVMContext(), getContext().getTypeSize(E->getType()));
50375034
5038- llvm::Value *Destination = EmitScalarExpr(E->getArg(0) );
5035+ Address DestAddr = CheckAtomicAlignment(*this, E );
50395036
50405037 llvm::Value *Exchange = EmitScalarExpr(E->getArg(1));
50415038 RTy = Exchange->getType();
@@ -5048,7 +5045,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
50485045 BuiltinID == Builtin::BI_InterlockedCompareExchangePointer_nf ?
50495046 AtomicOrdering::Monotonic : AtomicOrdering::SequentiallyConsistent;
50505047
5051- auto Result = Builder.CreateAtomicCmpXchg(Destination , Comparand, Exchange,
5048+ auto Result = Builder.CreateAtomicCmpXchg(DestAddr , Comparand, Exchange,
50525049 Ordering, Ordering);
50535050 Result->setVolatile(true);
50545051
@@ -11901,12 +11898,12 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
1190111898 }
1190211899
1190311900 case clang::AArch64::BI_InterlockedAdd: {
11904- Value *Arg0 = EmitScalarExpr(E->getArg(0) );
11905- Value *Arg1 = EmitScalarExpr(E->getArg(1));
11906- AtomicRMWInst *RMWI = Builder.CreateAtomicRMW(
11907- AtomicRMWInst::Add, Arg0, Arg1 ,
11908- llvm::AtomicOrdering::SequentiallyConsistent);
11909- return Builder.CreateAdd(RMWI, Arg1 );
11901+ Address DestAddr = CheckAtomicAlignment(*this, E );
11902+ Value *Val = EmitScalarExpr(E->getArg(1));
11903+ AtomicRMWInst *RMWI =
11904+ Builder.CreateAtomicRMW( AtomicRMWInst::Add, DestAddr, Val ,
11905+ llvm::AtomicOrdering::SequentiallyConsistent);
11906+ return Builder.CreateAdd(RMWI, Val );
1191011907 }
1191111908 }
1191211909
@@ -18219,7 +18216,7 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
1821918216 break;
1822018217 }
1822118218
18222- Value * Ptr = EmitScalarExpr(E->getArg(0) );
18219+ Address Ptr = CheckAtomicAlignment(*this, E );
1822318220 Value *Val = EmitScalarExpr(E->getArg(1));
1822418221
1822518222 ProcessOrderScopeAMDGCN(EmitScalarExpr(E->getArg(2)),
@@ -19108,9 +19105,10 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID,
1910819105
1910919106 case NVPTX::BI__nvvm_atom_add_gen_f:
1911019107 case NVPTX::BI__nvvm_atom_add_gen_d: {
19111- Value *Ptr = EmitScalarExpr (E->getArg(0));
19108+ Address DestAddr = EmitPointerWithAlignment (E->getArg(0));
1911219109 Value *Val = EmitScalarExpr(E->getArg(1));
19113- return Builder.CreateAtomicRMW(llvm::AtomicRMWInst::FAdd, Ptr, Val,
19110+
19111+ return Builder.CreateAtomicRMW(llvm::AtomicRMWInst::FAdd, DestAddr, Val,
1911419112 AtomicOrdering::SequentiallyConsistent);
1911519113 }
1911619114
0 commit comments