[ClangFE] Handle statement expressions properly with CheckAtomicAlignment().

Make CheckAtomicAlignment() return the computed pointer for reuse to avoid
emitting it twice.

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D148422
This commit is contained in:
Jonas Paulsson
2023-04-14 12:12:29 +02:00
parent dd3eb53275
commit 790c9ac529
2 changed files with 32 additions and 21 deletions

View File

@@ -170,6 +170,21 @@ static Value *EmitFromInt(CodeGenFunction &CGF, llvm::Value *V,
return V;
}
static llvm::Value *CheckAtomicAlignment(CodeGenFunction &CGF,
const CallExpr *E) {
ASTContext &Ctx = CGF.getContext();
Address Ptr = CGF.EmitPointerWithAlignment(E->getArg(0));
unsigned Bytes = Ptr.getElementType()->isPointerTy()
? Ctx.getTypeSizeInChars(Ctx.VoidPtrTy).getQuantity()
: Ptr.getElementType()->getScalarSizeInBits() / 8;
unsigned Align = Ptr.getAlignment().getQuantity();
if (Align % Bytes != 0) {
DiagnosticsEngine &Diags = CGF.CGM.getDiags();
Diags.Report(E->getBeginLoc(), diag::warn_sync_op_misaligned);
}
return Ptr.getPointer();
}
/// Utility to insert an atomic instruction based on Intrinsic::ID
/// and the expression node.
static Value *MakeBinaryAtomicValue(
@@ -182,7 +197,7 @@ static Value *MakeBinaryAtomicValue(
E->getArg(0)->getType()->getPointeeType()));
assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType()));
llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0));
llvm::Value *DestPtr = CheckAtomicAlignment(CGF, E);
unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace();
llvm::IntegerType *IntType =
@@ -224,23 +239,9 @@ static Value *EmitNontemporalLoad(CodeGenFunction &CGF, const CallExpr *E) {
return CGF.EmitLoadOfScalar(LV, E->getExprLoc());
}
static void CheckAtomicAlignment(CodeGenFunction &CGF, const CallExpr *E) {
ASTContext &Ctx = CGF.getContext();
Address Ptr = CGF.EmitPointerWithAlignment(E->getArg(0));
unsigned Bytes = Ptr.getElementType()->isPointerTy()
? Ctx.getTypeSizeInChars(Ctx.VoidPtrTy).getQuantity()
: Ptr.getElementType()->getScalarSizeInBits() / 8;
unsigned Align = Ptr.getAlignment().getQuantity();
if (Align % Bytes != 0) {
DiagnosticsEngine &Diags = CGF.CGM.getDiags();
Diags.Report(E->getBeginLoc(), diag::warn_sync_op_misaligned);
}
}
static RValue EmitBinaryAtomic(CodeGenFunction &CGF,
llvm::AtomicRMWInst::BinOp Kind,
const CallExpr *E) {
CheckAtomicAlignment(CGF, E);
return RValue::get(MakeBinaryAtomicValue(CGF, Kind, E));
}
@@ -252,14 +253,13 @@ static RValue EmitBinaryAtomicPost(CodeGenFunction &CGF,
const CallExpr *E,
Instruction::BinaryOps Op,
bool Invert = false) {
CheckAtomicAlignment(CGF, E);
QualType T = E->getType();
assert(E->getArg(0)->getType()->isPointerType());
assert(CGF.getContext().hasSameUnqualifiedType(T,
E->getArg(0)->getType()->getPointeeType()));
assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType()));
llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0));
llvm::Value *DestPtr = CheckAtomicAlignment(CGF, E);
unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace();
llvm::IntegerType *IntType =
@@ -300,9 +300,8 @@ static RValue EmitBinaryAtomicPost(CodeGenFunction &CGF,
/// invoke the function EmitAtomicCmpXchgForMSIntrin.
static Value *MakeAtomicCmpXchgValue(CodeGenFunction &CGF, const CallExpr *E,
bool ReturnBool) {
CheckAtomicAlignment(CGF, E);
QualType T = ReturnBool ? E->getArg(1)->getType() : E->getType();
llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0));
llvm::Value *DestPtr = CheckAtomicAlignment(CGF, E);
unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace();
llvm::IntegerType *IntType = llvm::IntegerType::get(
@@ -4045,8 +4044,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__sync_lock_release_4:
case Builtin::BI__sync_lock_release_8:
case Builtin::BI__sync_lock_release_16: {
CheckAtomicAlignment(*this, E);
Value *Ptr = EmitScalarExpr(E->getArg(0));
Value *Ptr = CheckAtomicAlignment(*this, E);
QualType ElTy = E->getArg(0)->getType()->getPointeeType();
CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy);
llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(),

View File

@@ -204,3 +204,16 @@ void f16() {
__int128 f17() {
return __sync_swap(&Ptr, Val);
}
// Test that a statement expression compiles.
// CHECK-LABEL: @f18(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[T_ADDR:%.*]] = alloca i128, align 8
// CHECK-NEXT: [[T:%.*]] = load i128, ptr [[TMP0:%.*]], align 8, !tbaa [[TBAA2]]
// CHECK-NEXT: store i128 [[T]], ptr [[T_ADDR]], align 8, !tbaa [[TBAA2]]
// CHECK-NEXT: [[TMP1:%.*]] = cmpxchg ptr [[T_ADDR]], i128 [[T]], i128 [[T]] seq_cst seq_cst, align 16
// CHECK-NEXT: ret void
//
void f18(__int128 t) {
__sync_bool_compare_and_swap(({int x = 1; &t;}), t, t);
}