mirror of
https://github.com/intel/llvm.git
synced 2026-01-23 07:58:23 +08:00
[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:
@@ -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(),
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user