[cfe-commits] r154789 - in /cfe/trunk: lib/CodeGen/CGCall.cpp lib/CodeGen/CGClass.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprAgg.cpp lib/CodeGen/CGExprCXX.cpp lib/CodeGen/CodeGenFunction.cpp lib/CodeGen/CodeGenFunction.h test/CodeGen/packed-nest-unpacked.c

Eli Friedman eli.friedman at gmail.com
Sun Apr 15 20:54:46 PDT 2012


Author: efriedma
Date: Sun Apr 15 22:54:45 2012
New Revision: 154789

URL: http://llvm.org/viewvc/llvm-project?rev=154789&view=rev
Log:
Propagate alignment on lvalues through EmitLValueForField.  PR12395.


Modified:
    cfe/trunk/lib/CodeGen/CGCall.cpp
    cfe/trunk/lib/CodeGen/CGClass.cpp
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CGExprAgg.cpp
    cfe/trunk/lib/CodeGen/CGExprCXX.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/test/CodeGen/packed-nest-unpacked.c

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=154789&r1=154788&r2=154789&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Sun Apr 15 22:54:45 2012
@@ -464,13 +464,12 @@
                                     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 @@
       }
       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 @@
         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 @@
   } 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 @@
         }
       }
       if (LargestFD) {
-        RValue FldRV = EmitRValueForField(Addr, LargestFD);
+        RValue FldRV = EmitRValueForField(LV, LargestFD);
         ExpandTypeToArgs(LargestFD->getType(), FldRV, Args, IRFuncTy);
       }
     } else {
@@ -1834,7 +1833,7 @@
            i != e; ++i) {
         FieldDecl *FD = *i;
 
-        RValue FldRV = EmitRValueForField(Addr, FD);
+        RValue FldRV = EmitRValueForField(LV, FD);
         ExpandTypeToArgs(FD->getType(), FldRV, Args, IRFuncTy);
       }
     }

Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=154789&r1=154788&r2=154789&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Sun Apr 15 22:54:45 2012
@@ -555,15 +555,17 @@
   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 @@
       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 @@
     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,

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=154789&r1=154788&r2=154789&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Sun Apr 15 22:54:45 2012
@@ -399,8 +399,8 @@
           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 @@
 
     // 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 @@
 }
 
 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 @@
   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::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::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 @@
   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);
 }
 
 //===--------------------------------------------------------------------===//

Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=154789&r1=154788&r2=154789&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Sun Apr 15 22:54:45 2012
@@ -348,7 +348,8 @@
     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 @@
     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 @@
     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 @@
         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 @@
     // 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 @@
         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);
     

Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=154789&r1=154788&r2=154789&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Sun Apr 15 22:54:45 2012
@@ -1815,13 +1815,16 @@
 
 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);

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=154789&r1=154788&r2=154789&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Sun Apr 15 22:54:45 2012
@@ -362,8 +362,12 @@
                                         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 {

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=154789&r1=154788&r2=154789&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Sun Apr 15 22:54:45 2012
@@ -2105,7 +2105,7 @@
   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 @@
   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,

Modified: cfe/trunk/test/CodeGen/packed-nest-unpacked.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/packed-nest-unpacked.c?rev=154789&r1=154788&r2=154789&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/packed-nest-unpacked.c (original)
+++ cfe/trunk/test/CodeGen/packed-nest-unpacked.c Sun Apr 15 22:54:45 2012
@@ -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 @@
   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];
+}





More information about the cfe-commits mailing list