Propagate alignment on lvalues through EmitLValueForField. PR12395.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154789 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eli Friedman 2012-04-16 03:54:45 +00:00
Родитель c5086f08be
Коммит 377ecc7996
8 изменённых файлов: 102 добавлений и 80 удалений

Просмотреть файл

@ -464,13 +464,12 @@ CodeGenFunction::ExpandTypeFromArgs(QualType Ty, LValue LV,
llvm::Function::arg_iterator AI) {
assert(LV.isSimple() &&
"Unexpected non-simple lvalue during struct expansion.");
llvm::Value *Addr = LV.getAddress();
if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) {
unsigned NumElts = AT->getSize().getZExtValue();
QualType EltTy = AT->getElementType();
for (unsigned Elt = 0; Elt < NumElts; ++Elt) {
llvm::Value *EltAddr = Builder.CreateConstGEP2_32(Addr, 0, Elt);
llvm::Value *EltAddr = Builder.CreateConstGEP2_32(LV.getAddress(), 0, Elt);
LValue LV = MakeAddrLValue(EltAddr, EltTy);
AI = ExpandTypeFromArgs(EltTy, LV, AI);
}
@ -495,8 +494,8 @@ CodeGenFunction::ExpandTypeFromArgs(QualType Ty, LValue LV,
}
if (LargestFD) {
// FIXME: What are the right qualifiers here?
LValue LV = EmitLValueForField(Addr, LargestFD, 0);
AI = ExpandTypeFromArgs(LargestFD->getType(), LV, AI);
LValue SubLV = EmitLValueForField(LV, LargestFD);
AI = ExpandTypeFromArgs(LargestFD->getType(), SubLV, AI);
}
} else {
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
@ -505,15 +504,15 @@ CodeGenFunction::ExpandTypeFromArgs(QualType Ty, LValue LV,
QualType FT = FD->getType();
// FIXME: What are the right qualifiers here?
LValue LV = EmitLValueForField(Addr, FD, 0);
AI = ExpandTypeFromArgs(FT, LV, AI);
LValue SubLV = EmitLValueForField(LV, FD);
AI = ExpandTypeFromArgs(FT, SubLV, AI);
}
}
} else if (const ComplexType *CT = Ty->getAs<ComplexType>()) {
QualType EltTy = CT->getElementType();
llvm::Value *RealAddr = Builder.CreateStructGEP(Addr, 0, "real");
llvm::Value *RealAddr = Builder.CreateStructGEP(LV.getAddress(), 0, "real");
EmitStoreThroughLValue(RValue::get(AI++), MakeAddrLValue(RealAddr, EltTy));
llvm::Value *ImagAddr = Builder.CreateStructGEP(Addr, 1, "imag");
llvm::Value *ImagAddr = Builder.CreateStructGEP(LV.getAddress(), 1, "imag");
EmitStoreThroughLValue(RValue::get(AI++), MakeAddrLValue(ImagAddr, EltTy));
} else {
EmitStoreThroughLValue(RValue::get(AI), LV);
@ -1808,7 +1807,7 @@ void CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV,
} else if (const RecordType *RT = Ty->getAs<RecordType>()) {
RecordDecl *RD = RT->getDecl();
assert(RV.isAggregate() && "Unexpected rvalue during struct expansion");
llvm::Value *Addr = RV.getAggregateAddr();
LValue LV = MakeAddrLValue(RV.getAggregateAddr(), Ty);
if (RD->isUnion()) {
const FieldDecl *LargestFD = 0;
@ -1826,7 +1825,7 @@ void CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV,
}
}
if (LargestFD) {
RValue FldRV = EmitRValueForField(Addr, LargestFD);
RValue FldRV = EmitRValueForField(LV, LargestFD);
ExpandTypeToArgs(LargestFD->getType(), FldRV, Args, IRFuncTy);
}
} else {
@ -1834,7 +1833,7 @@ void CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV,
i != e; ++i) {
FieldDecl *FD = *i;
RValue FldRV = EmitRValueForField(Addr, FD);
RValue FldRV = EmitRValueForField(LV, FD);
ExpandTypeToArgs(FD->getType(), FldRV, Args, IRFuncTy);
}
}

Просмотреть файл

@ -555,15 +555,17 @@ static void EmitMemberInitializer(CodeGenFunction &CGF,
QualType FieldType = Field->getType();
llvm::Value *ThisPtr = CGF.LoadCXXThis();
QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl);
LValue LHS;
// If we are initializing an anonymous union field, drill down to the field.
if (MemberInit->isIndirectMemberInitializer()) {
LHS = CGF.EmitLValueForAnonRecordField(ThisPtr,
MemberInit->getIndirectMember(), 0);
FieldType = MemberInit->getIndirectMember()->getAnonField()->getType();
} else {
LHS = CGF.EmitLValueForFieldInitialization(ThisPtr, Field, 0);
LValue ThisLHSLV = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy);
LHS = CGF.EmitLValueForFieldInitialization(ThisLHSLV, Field);
}
// Special case: if we are in a copy or move constructor, and we are copying
@ -585,7 +587,8 @@ static void EmitMemberInitializer(CodeGenFunction &CGF,
unsigned SrcArgIndex = Args.size() - 1;
llvm::Value *SrcPtr
= CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(Args[SrcArgIndex]));
LValue Src = CGF.EmitLValueForFieldInitialization(SrcPtr, Field, 0);
LValue ThisRHSLV = CGF.MakeNaturalAlignAddrLValue(SrcPtr, RecordTy);
LValue Src = CGF.EmitLValueForFieldInitialization(ThisRHSLV, Field);
// Copy the aggregate.
CGF.EmitAggregateCopy(LHS.getAddress(), Src.getAddress(), FieldType,
@ -978,7 +981,9 @@ namespace {
void Emit(CodeGenFunction &CGF, Flags flags) {
// Find the address of the field.
llvm::Value *thisValue = CGF.LoadCXXThis();
LValue LV = CGF.EmitLValueForField(thisValue, field, /*CVRQualifiers=*/0);
QualType RecordTy = CGF.getContext().getTagDeclType(field->getParent());
LValue ThisLV = CGF.MakeAddrLValue(thisValue, RecordTy);
LValue LV = CGF.EmitLValueForField(ThisLV, field);
assert(LV.isSimple());
CGF.emitDestroy(LV.getAddress(), field->getType(), destroyer,

Просмотреть файл

@ -399,8 +399,8 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
break;
case SubobjectAdjustment::FieldAdjustment: {
LValue LV =
CGF.EmitLValueForField(Object, Adjustment.Field, 0);
LValue LV = CGF.MakeAddrLValue(Object, E->getType());
LV = CGF.EmitLValueForField(LV, Adjustment.Field);
if (LV.isSimple()) {
Object = LV.getAddress();
break;
@ -1570,8 +1570,12 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
// Use special handling for lambdas.
if (!V) {
if (FieldDecl *FD = LambdaCaptureFields.lookup(VD))
return EmitLValueForField(CXXABIThisValue, FD, 0);
if (FieldDecl *FD = LambdaCaptureFields.lookup(VD)) {
QualType LambdaTagType = getContext().getTagDeclType(FD->getParent());
LValue LambdaLV = MakeNaturalAlignAddrLValue(CXXABIThisValue,
LambdaTagType);
return EmitLValueForField(LambdaLV, FD);
}
assert(isa<BlockDecl>(CurCodeDecl) && E->refersToEnclosingLocal());
CharUnits alignment = getContext().getDeclAlign(VD);
@ -1966,32 +1970,19 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
}
LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
bool isNonGC = false;
Expr *BaseExpr = E->getBase();
llvm::Value *BaseValue = NULL;
Qualifiers BaseQuals;
// If this is s.x, emit s as an lvalue. If it is s->x, emit s as a scalar.
if (E->isArrow()) {
BaseValue = EmitScalarExpr(BaseExpr);
const PointerType *PTy =
BaseExpr->getType()->getAs<PointerType>();
BaseQuals = PTy->getPointeeType().getQualifiers();
} else {
LValue BaseLV = EmitLValue(BaseExpr);
if (BaseLV.isNonGC())
isNonGC = true;
// FIXME: this isn't right for bitfields.
BaseValue = BaseLV.getAddress();
QualType BaseTy = BaseExpr->getType();
BaseQuals = BaseTy.getQualifiers();
}
LValue BaseLV;
if (E->isArrow())
BaseLV = MakeNaturalAlignAddrLValue(EmitScalarExpr(BaseExpr),
BaseExpr->getType()->getPointeeType());
else
BaseLV = EmitLValue(BaseExpr);
NamedDecl *ND = E->getMemberDecl();
if (FieldDecl *Field = dyn_cast<FieldDecl>(ND)) {
LValue LV = EmitLValueForField(BaseValue, Field,
BaseQuals.getCVRQualifiers());
LV.setNonGC(isNonGC);
LValue LV = EmitLValueForField(BaseLV, Field);
setObjCGCLValueClass(getContext(), E, LV);
return LV;
}
@ -2025,8 +2016,10 @@ LValue CodeGenFunction::EmitLValueForAnonRecordField(llvm::Value *BaseValue,
IndirectFieldDecl::chain_iterator I = Field->chain_begin(),
IEnd = Field->chain_end();
while (true) {
LValue LV = EmitLValueForField(BaseValue, cast<FieldDecl>(*I),
CVRQualifiers);
QualType RecordTy =
getContext().getTypeDeclType(cast<FieldDecl>(*I)->getParent());
LValue LV = EmitLValueForField(MakeAddrLValue(BaseValue, RecordTy),
cast<FieldDecl>(*I));
if (++I == IEnd) return LV;
assert(LV.isSimple());
@ -2035,19 +2028,25 @@ LValue CodeGenFunction::EmitLValueForAnonRecordField(llvm::Value *BaseValue,
}
}
LValue CodeGenFunction::EmitLValueForField(llvm::Value *baseAddr,
const FieldDecl *field,
unsigned cvr) {
LValue CodeGenFunction::EmitLValueForField(LValue base,
const FieldDecl *field) {
if (field->isBitField())
return EmitLValueForBitfield(baseAddr, field, cvr);
return EmitLValueForBitfield(base.getAddress(), field,
base.getVRQualifiers());
const RecordDecl *rec = field->getParent();
QualType type = field->getType();
CharUnits alignment = getContext().getDeclAlign(field);
// FIXME: It should be impossible to have an LValue without alignment for a
// complete type.
if (!base.getAlignment().isZero())
alignment = std::min(alignment, base.getAlignment());
bool mayAlias = rec->hasAttr<MayAliasAttr>();
llvm::Value *addr = baseAddr;
llvm::Value *addr = base.getAddress();
unsigned cvr = base.getVRQualifiers();
if (rec->isUnion()) {
// For unions, there is no pointer adjustment.
assert(!type->isReferenceType() && "union has reference member");
@ -2110,30 +2109,33 @@ LValue CodeGenFunction::EmitLValueForField(llvm::Value *baseAddr,
}
LValue
CodeGenFunction::EmitLValueForFieldInitialization(llvm::Value *BaseValue,
const FieldDecl *Field,
unsigned CVRQualifiers) {
CodeGenFunction::EmitLValueForFieldInitialization(LValue Base,
const FieldDecl *Field) {
QualType FieldType = Field->getType();
if (!FieldType->isReferenceType())
return EmitLValueForField(BaseValue, Field, CVRQualifiers);
return EmitLValueForField(Base, Field);
const CGRecordLayout &RL =
CGM.getTypes().getCGRecordLayout(Field->getParent());
unsigned idx = RL.getLLVMFieldNo(Field);
llvm::Value *V = Builder.CreateStructGEP(BaseValue, idx);
llvm::Value *V = Builder.CreateStructGEP(Base.getAddress(), idx);
assert(!FieldType.getObjCGCAttr() && "fields cannot have GC attrs");
// Make sure that the address is pointing to the right type. This is critical
// for both unions and structs. A union needs a bitcast, a struct element
// will need a bitcast if the LLVM type laid out doesn't match the desired
// type.
llvm::Type *llvmType = ConvertTypeForMem(FieldType);
unsigned AS = cast<llvm::PointerType>(V->getType())->getAddressSpace();
V = Builder.CreateBitCast(V, llvmType->getPointerTo(AS));
V = EmitBitCastOfLValueToProperType(*this, V, llvmType, Field->getName());
CharUnits Alignment = getContext().getDeclAlign(Field);
// FIXME: It should be impossible to have an LValue without alignment for a
// complete type.
if (!Base.getAlignment().isZero())
Alignment = std::min(Alignment, Base.getAlignment());
return MakeAddrLValue(V, FieldType, Alignment);
}
@ -2371,18 +2373,18 @@ LValue CodeGenFunction::EmitMaterializeTemporaryExpr(
return MakeAddrLValue(RV.getScalarVal(), E->getType());
}
RValue CodeGenFunction::EmitRValueForField(llvm::Value *Addr,
RValue CodeGenFunction::EmitRValueForField(LValue LV,
const FieldDecl *FD) {
QualType FT = FD->getType();
// FIXME: What are the right qualifiers here?
LValue LV = EmitLValueForField(Addr, FD, 0);
LValue FieldLV = EmitLValueForField(LV, FD);
if (FT->isAnyComplexType())
// FIXME: Volatile?
return RValue::getComplex(LoadComplexFromAddr(LV.getAddress(), false));
return RValue::getComplex(
LoadComplexFromAddr(FieldLV.getAddress(),
FieldLV.isVolatileQualified()));
else if (CodeGenFunction::hasAggregateLLVMType(FT))
return LV.asAggregateRValue();
return FieldLV.asAggregateRValue();
return EmitLoadOfLValue(LV);
return EmitLoadOfLValue(FieldLV);
}
//===--------------------------------------------------------------------===//

Просмотреть файл

@ -348,7 +348,8 @@ void AggExprEmitter::EmitStdInitializerList(llvm::Value *destPtr,
CGF.ErrorUnsupported(initList, "weird std::initializer_list");
return;
}
LValue start = CGF.EmitLValueForFieldInitialization(destPtr, *field, 0);
LValue DestLV = CGF.MakeNaturalAlignAddrLValue(destPtr, initList->getType());
LValue start = CGF.EmitLValueForFieldInitialization(DestLV, *field);
llvm::Value *arrayStart = Builder.CreateStructGEP(alloc, 0, "arraystart");
CGF.EmitStoreThroughLValue(RValue::get(arrayStart), start);
++field;
@ -357,7 +358,7 @@ void AggExprEmitter::EmitStdInitializerList(llvm::Value *destPtr,
CGF.ErrorUnsupported(initList, "weird std::initializer_list");
return;
}
LValue endOrLength = CGF.EmitLValueForFieldInitialization(destPtr, *field, 0);
LValue endOrLength = CGF.EmitLValueForFieldInitialization(DestLV, *field);
if (ctx.hasSameType(field->getType(), elementPtr)) {
// End pointer.
llvm::Value *arrayEnd = Builder.CreateStructGEP(alloc,numInits, "arrayend");
@ -912,7 +913,9 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
return;
}
llvm::Value *DestPtr = EnsureSlot(E->getType()).getAddr();
AggValueSlot Dest = EnsureSlot(E->getType());
LValue DestLV = CGF.MakeAddrLValue(Dest.getAddr(), E->getType(),
Dest.getAlignment());
// Handle initialization of an array.
if (E->getType()->isArrayType()) {
@ -923,11 +926,11 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
CGF.getContext().getAsArrayType(E->getType())->getElementType();
llvm::PointerType *APType =
cast<llvm::PointerType>(DestPtr->getType());
cast<llvm::PointerType>(Dest.getAddr()->getType());
llvm::ArrayType *AType =
cast<llvm::ArrayType>(APType->getElementType());
EmitArrayInit(DestPtr, AType, elementType, E);
EmitArrayInit(Dest.getAddr(), AType, elementType, E);
return;
}
@ -960,7 +963,7 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
// FIXME: volatility
FieldDecl *Field = E->getInitializedFieldInUnion();
LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, Field, 0);
LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestLV, Field);
if (NumInitElements) {
// Store the initializer into the field
EmitInitializationToLValue(E->getInit(0), FieldLoc);
@ -998,8 +1001,8 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
CGF.getTypes().isZeroInitializable(E->getType()))
break;
// FIXME: volatility
LValue LV = CGF.EmitLValueForFieldInitialization(DestPtr, *field, 0);
LValue LV = CGF.EmitLValueForFieldInitialization(DestLV, *field);
// We never generate write-barries for initialized fields.
LV.setNonGC(true);

Просмотреть файл

@ -1815,13 +1815,16 @@ llvm::Value *CodeGenFunction::EmitDynamicCast(llvm::Value *Value,
void CodeGenFunction::EmitLambdaExpr(const LambdaExpr *E, AggValueSlot Slot) {
RunCleanupsScope Scope(*this);
LValue SlotLV = MakeAddrLValue(Slot.getAddr(), E->getType(),
Slot.getAlignment());
CXXRecordDecl::field_iterator CurField = E->getLambdaClass()->field_begin();
for (LambdaExpr::capture_init_iterator i = E->capture_init_begin(),
e = E->capture_init_end();
i != e; ++i, ++CurField) {
// Emit initialization
LValue LV = EmitLValueForFieldInitialization(Slot.getAddr(), *CurField, 0);
LValue LV = EmitLValueForFieldInitialization(SlotLV, *CurField);
ArrayRef<VarDecl *> ArrayIndexes;
if (CurField->getType()->isArrayType())
ArrayIndexes = E->getCaptureInitIndexVars(i);

Просмотреть файл

@ -362,8 +362,12 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
LambdaThisCaptureField);
if (LambdaThisCaptureField) {
// If this lambda captures this, load it.
LValue ThisLValue = EmitLValueForField(CXXABIThisValue,
LambdaThisCaptureField, 0);
QualType LambdaTagType =
getContext().getTagDeclType(LambdaThisCaptureField->getParent());
LValue LambdaLV = MakeNaturalAlignAddrLValue(CXXABIThisValue,
LambdaTagType);
LValue ThisLValue = EmitLValueForField(LambdaLV,
LambdaThisCaptureField);
CXXThisValue = EmitLoadOfLValue(ThisLValue).getScalarVal();
}
} else {

Просмотреть файл

@ -2105,7 +2105,7 @@ public:
LValue EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E);
LValue EmitOpaqueValueLValue(const OpaqueValueExpr *e);
RValue EmitRValueForField(llvm::Value *Addr, const FieldDecl *FD);
RValue EmitRValueForField(LValue LV, const FieldDecl *FD);
class ConstantEmission {
llvm::PointerIntPair<llvm::Constant*, 1, bool> ValueAndIsReference;
@ -2146,15 +2146,13 @@ public:
LValue EmitLValueForAnonRecordField(llvm::Value* Base,
const IndirectFieldDecl* Field,
unsigned CVRQualifiers);
LValue EmitLValueForField(llvm::Value* Base, const FieldDecl* Field,
unsigned CVRQualifiers);
LValue EmitLValueForField(LValue Base, const FieldDecl* Field);
/// EmitLValueForFieldInitialization - Like EmitLValueForField, except that
/// if the Field is a reference, this will return the address of the reference
/// and not the address of the value stored in the reference.
LValue EmitLValueForFieldInitialization(llvm::Value* Base,
const FieldDecl* Field,
unsigned CVRQualifiers);
LValue EmitLValueForFieldInitialization(LValue Base,
const FieldDecl* Field);
LValue EmitLValueForIvar(QualType ObjectTy,
llvm::Value* Base, const ObjCIvarDecl *Ivar,

Просмотреть файл

@ -1,11 +1,11 @@
// RUN: %clang_cc1 %s -triple x86_64-apple-macosx10.7.2 -emit-llvm -o - | FileCheck %s
// <rdar://problem/10463337>
struct X { int x[6]; };
struct Y { char x[13]; struct X y; } __attribute((packed));
struct Y g;
void f(struct X);
// <rdar://problem/10463337>
struct X test1() {
// CHECK: @test1
// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* bitcast (%struct.X* getelementptr inbounds (%struct.Y* @g, i32 0, i32 1) to i8*), i64 24, i32 1, i1 false)
@ -24,8 +24,16 @@ void test3(struct X a) {
g.y = a;
}
// <rdar://problem/10530444>
void test4() {
// CHECK: @test4
// FIXME: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* bitcast (%struct.X* getelementptr inbounds (%struct.Y* @g, i32 0, i32 1) to i8*), i64 24, i32 1, i1 false)
f(g.y);
}
// PR12395
int test5() {
// CHECK: @test5
// CHECK: load i32* getelementptr inbounds (%struct.Y* @g, i32 0, i32 1, i32 0, i64 0), align 1
return g.y.x[0];
}