// reference.
} else {
// Load scalar value from indirect argument.
- V = EmitLoadOfScalar(V, false, Ty);
+ unsigned Alignment = getContext().getTypeAlignInChars(Ty).getQuantity();
+ V = EmitLoadOfScalar(V, false, Alignment, Ty);
if (!getContext().typesAreCompatible(Ty, Arg->getType())) {
// This must be a promotion, for something like
// "void a(x) short x; {..."
// Match to what EmitParmDecl is expecting for this type.
if (!CodeGenFunction::hasAggregateLLVMType(Ty)) {
- V = EmitLoadOfScalar(V, false, Ty);
+ V = EmitLoadOfScalar(V, false, AlignmentToUse, Ty);
if (!getContext().typesAreCompatible(Ty, Arg->getType())) {
// This must be a promotion, for something like
// "void a(x) short x; {..."
const ABIArgInfo &RetAI = FI.getReturnInfo();
switch (RetAI.getKind()) {
- case ABIArgInfo::Indirect:
+ case ABIArgInfo::Indirect: {
+ unsigned Alignment = getContext().getTypeAlignInChars(RetTy).getQuantity();
if (RetTy->isAnyComplexType()) {
ComplexPairTy RT = LoadComplexFromAddr(ReturnValue, false);
StoreComplexToAddr(RT, CurFn->arg_begin(), false);
// Do nothing; aggregrates get evaluated directly into the destination.
} else {
EmitStoreOfScalar(Builder.CreateLoad(ReturnValue), CurFn->arg_begin(),
- false, RetTy);
+ false, Alignment, RetTy);
}
break;
+ }
case ABIArgInfo::Extend:
case ABIArgInfo::Direct:
if (hasAggregateLLVMType(ArgType))
return RValue::getAggregate(Local);
- return RValue::get(EmitLoadOfScalar(Local, false, ArgType));
+ unsigned Alignment = getContext().getDeclAlign(Param).getQuantity();
+ return RValue::get(EmitLoadOfScalar(Local, false, Alignment, ArgType));
}
RValue CodeGenFunction::EmitCallArg(const Expr *E, QualType ArgType) {
const ABIArgInfo &ArgInfo = info_it->info;
RValue RV = I->first;
+ unsigned Alignment =
+ getContext().getTypeAlignInChars(I->second).getQuantity();
switch (ArgInfo.getKind()) {
- case ABIArgInfo::Indirect:
+ case ABIArgInfo::Indirect: {
if (RV.isScalar() || RV.isComplex()) {
// Make a temporary alloca to pass the argument.
Args.push_back(CreateMemTemp(I->second));
if (RV.isScalar())
- EmitStoreOfScalar(RV.getScalarVal(), Args.back(), false, I->second);
+ EmitStoreOfScalar(RV.getScalarVal(), Args.back(), false,
+ Alignment, I->second);
else
StoreComplexToAddr(RV.getComplexVal(), Args.back(), false);
} else {
Args.push_back(RV.getAggregateAddr());
}
break;
+ }
case ABIArgInfo::Ignore:
break;
llvm::Value *SrcPtr;
if (RV.isScalar()) {
SrcPtr = CreateMemTemp(I->second, "coerce");
- EmitStoreOfScalar(RV.getScalarVal(), SrcPtr, false, I->second);
+ EmitStoreOfScalar(RV.getScalarVal(), SrcPtr, false, Alignment,
+ I->second);
} else if (RV.isComplex()) {
SrcPtr = CreateMemTemp(I->second, "coerce");
StoreComplexToAddr(RV.getComplexVal(), SrcPtr, false);
CI->setName("call");
switch (RetAI.getKind()) {
- case ABIArgInfo::Indirect:
+ case ABIArgInfo::Indirect: {
+ unsigned Alignment = getContext().getTypeAlignInChars(RetTy).getQuantity();
if (RetTy->isAnyComplexType())
return RValue::getComplex(LoadComplexFromAddr(Args[0], false));
if (CodeGenFunction::hasAggregateLLVMType(RetTy))
return RValue::getAggregate(Args[0]);
- return RValue::get(EmitLoadOfScalar(Args[0], false, RetTy));
+ return RValue::get(EmitLoadOfScalar(Args[0], false, Alignment, RetTy));
+ }
case ABIArgInfo::Ignore:
// If we are ignoring an argument that had a result, make sure to
}
CreateCoercedStore(CI, StorePtr, DestIsVolatile, *this);
+ unsigned Alignment = getContext().getTypeAlignInChars(RetTy).getQuantity();
if (RetTy->isAnyComplexType())
return RValue::getComplex(LoadComplexFromAddr(DestPtr, false));
if (CodeGenFunction::hasAggregateLLVMType(RetTy))
return RValue::getAggregate(DestPtr);
- return RValue::get(EmitLoadOfScalar(DestPtr, false, RetTy));
+ return RValue::get(EmitLoadOfScalar(DestPtr, false, Alignment, RetTy));
}
case ABIArgInfo::Expand:
void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D,
SpecialInitFn *SpecialInit) {
QualType Ty = D.getType();
+ unsigned Alignment = getContext().getDeclAlign(&D).getQuantity();
bool isByRef = D.hasAttr<BlocksAttr>();
bool needsDispose = false;
CharUnits Align = CharUnits::Zero();
}
} else if (Ty->isReferenceType()) {
RValue RV = EmitReferenceBindingToExpr(Init, &D);
- EmitStoreOfScalar(RV.getScalarVal(), Loc, false, Ty);
+ EmitStoreOfScalar(RV.getScalarVal(), Loc, false, Alignment, Ty);
} else if (!hasAggregateLLVMType(Init->getType())) {
llvm::Value *V = EmitScalarExpr(Init);
- EmitStoreOfScalar(V, Loc, isVolatile, Ty);
+ EmitStoreOfScalar(V, Loc, isVolatile, Alignment, Ty);
} else if (Init->getType()->isAnyComplexType()) {
EmitComplexExprIntoAddr(Init, Loc, isVolatile);
} else {
DeclPtr = CreateMemTemp(Ty, D.getName() + ".addr");
// Store the initial value into the alloca.
- EmitStoreOfScalar(Arg, DeclPtr, CTy.isVolatileQualified(), Ty);
+ unsigned Alignment = getContext().getDeclAlign(&D).getQuantity();
+ EmitStoreOfScalar(Arg, DeclPtr, CTy.isVolatileQualified(), Alignment, Ty);
}
Arg->setName(D.getName());
QualType T = D.getType();
bool isVolatile = Context.getCanonicalType(T).isVolatileQualified();
+ unsigned Alignment = Context.getDeclAlign(&D).getQuantity();
if (!CGF.hasAggregateLLVMType(T)) {
llvm::Value *V = CGF.EmitScalarExpr(Init);
- CGF.EmitStoreOfScalar(V, DeclPtr, isVolatile, T);
+ CGF.EmitStoreOfScalar(V, DeclPtr, isVolatile, Alignment, T);
} else if (T->isAnyComplexType()) {
CGF.EmitComplexExprIntoAddr(Init, DeclPtr, isVolatile);
} else {
return;
}
+ unsigned Alignment = getContext().getDeclAlign(&D).getQuantity();
RValue RV = EmitReferenceBindingToExpr(Init, &D);
- EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, T);
+ EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, Alignment, T);
}
void
}
if (D.getType()->isReferenceType()) {
+ unsigned Alignment = getContext().getDeclAlign(&D).getQuantity();
QualType T = D.getType();
RValue RV = EmitReferenceBindingToExpr(D.getInit(), &D);
- EmitStoreOfScalar(RV.getScalarVal(), GV, /*Volatile=*/false, T);
-
+ EmitStoreOfScalar(RV.getScalarVal(), GV, /*Volatile=*/false, Alignment, T);
} else
EmitDeclInit(*this, D, GV);
CGF.StoreComplexToAddr(CGF.LoadComplexFromAddr(Cast, /*volatile*/ false),
ParamAddr, /*volatile*/ false);
} else {
+ unsigned Alignment =
+ CGF.getContext().getDeclAlign(&CatchParam).getQuantity();
llvm::Value *ExnLoad = CGF.Builder.CreateLoad(Cast, "exn.scalar");
- CGF.EmitStoreOfScalar(ExnLoad, ParamAddr, /*volatile*/ false, CatchType);
+ CGF.EmitStoreOfScalar(ExnLoad, ParamAddr, /*volatile*/ false, Alignment,
+ CatchType);
}
return;
}
ReferenceTemporary = CreateReferenceTemporary(CGF, E->getType(),
InitializedDecl);
+
+ unsigned Alignment =
+ CGF.getContext().getTypeAlignInChars(E->getType()).getQuantity();
if (RV.isScalar())
CGF.EmitStoreOfScalar(RV.getScalarVal(), ReferenceTemporary,
- /*Volatile=*/false, E->getType());
+ /*Volatile=*/false, Alignment, E->getType());
else
CGF.StoreComplexToAddr(RV.getComplexVal(), ReferenceTemporary,
/*Volatile=*/false);
}
llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
- QualType Ty) {
+ unsigned Alignment, QualType Ty) {
llvm::LoadInst *Load = Builder.CreateLoad(Addr, "tmp");
if (Volatile)
Load->setVolatile(true);
+ if (Alignment)
+ Load->setAlignment(Alignment);
// Bool can have different representation in memory than in registers.
llvm::Value *V = Load;
}
void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr,
- bool Volatile, QualType Ty) {
+ bool Volatile, unsigned Alignment,
+ QualType Ty) {
if (Ty->isBooleanType()) {
// Bool can have different representation in memory than in registers.
const llvm::PointerType *DstPtr = cast<llvm::PointerType>(Addr->getType());
Value = Builder.CreateIntCast(Value, DstPtr->getElementType(), false);
}
- Builder.CreateStore(Value, Addr, Volatile);
+
+ llvm::StoreInst *Store = Builder.CreateStore(Value, Addr, Volatile);
+ if (Alignment)
+ Store->setAlignment(Alignment);
}
/// EmitLoadOfLValue - Given an expression that represents a value lvalue, this
// Simple scalar l-value.
//
// FIXME: We shouldn't have to use isSingleValueType here.
+ //
+ // FIXME: Pass alignment!
if (EltTy->isSingleValueType())
return RValue::get(EmitLoadOfScalar(Ptr, LV.isVolatileQualified(),
- ExprType));
+ /*Alignment=*/0, ExprType));
assert(ExprType->isFunctionType() && "Unknown scalar value");
return RValue::get(Ptr);
}
assert(Src.isScalar() && "Can't emit an agg store with this method");
+ // FIXME: Pass alignment.
EmitStoreOfScalar(Src.getScalarVal(), Dst.getAddress(),
- Dst.isVolatileQualified(), Ty);
+ Dst.isVolatileQualified(), /*Alignment=*/0, Ty);
}
void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
const Expr *Init = E->getConstructorArg(0);
QualType AllocType = E->getAllocatedType();
-
+
+ unsigned Alignment =
+ CGF.getContext().getTypeAlignInChars(AllocType).getQuantity();
if (!CGF.hasAggregateLLVMType(AllocType))
CGF.EmitStoreOfScalar(CGF.EmitScalarExpr(Init), NewPtr,
- AllocType.isVolatileQualified(), AllocType);
+ AllocType.isVolatileQualified(), Alignment,
+ AllocType);
else if (AllocType->isAnyComplexType())
CGF.EmitComplexExprIntoAddr(Init, NewPtr,
AllocType.isVolatileQualified());
/// care to appropriately convert from the memory representation to
/// the LLVM value representation.
llvm::Value *EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
- QualType Ty);
+ unsigned Alignment, QualType Ty);
/// EmitStoreOfScalar - Store a scalar value to an address, taking
/// care to appropriately convert from the memory representation to
/// the LLVM value representation.
void EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr,
- bool Volatile, QualType Ty);
+ bool Volatile, unsigned Alignment, QualType Ty);
/// EmitLoadOfLValue - Given an expression that represents a value lvalue,
/// this method emits the address of the lvalue, then loads the result as an