[cfe-commits] r144745 - in /cfe/trunk: lib/CodeGen/CGExpr.cpp lib/CodeGen/CodeGenFunction.h test/CodeGenCXX/references.cpp

Eli Friedman eli.friedman at gmail.com
Tue Nov 15 16:42:57 PST 2011


Author: efriedma
Date: Tue Nov 15 18:42:57 2011
New Revision: 144745

URL: http://llvm.org/viewvc/llvm-project?rev=144745&view=rev
Log:
Fix a bunch of really nasty bugs in how we compute alignment for reference lvalues.  PR11376.


Modified:
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/test/CodeGenCXX/references.cpp

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=144745&r1=144744&r2=144745&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Nov 15 18:42:57 2011
@@ -1319,14 +1319,19 @@
          "Var decl must have external storage or be a file var decl!");
 
   llvm::Value *V = CGF.CGM.GetAddrOfGlobalVar(VD);
-  if (VD->getType()->isReferenceType())
-    V = CGF.Builder.CreateLoad(V);
-  
-  V = EmitBitCastOfLValueToProperType(CGF, V,
-                                CGF.getTypes().ConvertTypeForMem(E->getType()));
-
+  llvm::Type *RealVarTy = CGF.getTypes().ConvertTypeForMem(VD->getType());
+  V = EmitBitCastOfLValueToProperType(CGF, V, RealVarTy);
   unsigned Alignment = CGF.getContext().getDeclAlign(VD).getQuantity();
-  LValue LV = CGF.MakeAddrLValue(V, E->getType(), Alignment);
+  QualType T = E->getType();
+  LValue LV;
+  if (VD->getType()->isReferenceType()) {
+    llvm::LoadInst *LI = CGF.Builder.CreateLoad(V);
+    LI->setAlignment(Alignment);
+    V = LI;
+    LV = CGF.MakeNaturalAlignAddrLValue(V, T);
+  } else {
+    LV = CGF.MakeAddrLValue(V, E->getType(), Alignment);
+  }
   setObjCGCLValueClass(CGF.getContext(), E, LV);
   return LV;
 }
@@ -1353,6 +1358,7 @@
 LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
   const NamedDecl *ND = E->getDecl();
   unsigned Alignment = getContext().getDeclAlign(ND).getQuantity();
+  QualType T = E->getType();
 
   if (ND->hasAttr<WeakRefAttr>()) {
     const ValueDecl *VD = cast<ValueDecl>(ND);
@@ -1377,14 +1383,17 @@
 
     if (VD->hasAttr<BlocksAttr>())
       V = BuildBlockByrefAddress(V, VD);
-    
-    if (VD->getType()->isReferenceType())
-      V = Builder.CreateLoad(V);
 
-    V = EmitBitCastOfLValueToProperType(*this, V,
-                                    getTypes().ConvertTypeForMem(E->getType()));
+    LValue LV;
+    if (VD->getType()->isReferenceType()) {
+      llvm::LoadInst *LI = Builder.CreateLoad(V);
+      LI->setAlignment(Alignment);
+      V = LI;
+      LV = MakeNaturalAlignAddrLValue(V, T);
+    } else {
+      LV = MakeAddrLValue(V, T, Alignment);
+    }
 
-    LValue LV = MakeAddrLValue(V, E->getType(), Alignment);
     if (NonGCable) {
       LV.getQuals().removeObjCGCAttr();
       LV.setNonGC(true);
@@ -1843,6 +1852,7 @@
 
   const RecordDecl *rec = field->getParent();
   QualType type = field->getType();
+  unsigned alignment = getContext().getDeclAlign(field).getQuantity();
 
   bool mayAlias = rec->hasAttr<MayAliasAttr>();
 
@@ -1859,6 +1869,7 @@
     if (const ReferenceType *refType = type->getAs<ReferenceType>()) {
       llvm::LoadInst *load = Builder.CreateLoad(addr, "ref");
       if (cvr & Qualifiers::Volatile) load->setVolatile(true);
+      load->setAlignment(alignment);
 
       if (CGM.shouldUseTBAA()) {
         llvm::MDNode *tbaa;
@@ -1872,6 +1883,10 @@
       addr = load;
       mayAlias = false;
       type = refType->getPointeeType();
+      if (type->isIncompleteType())
+        alignment = 0;
+      else
+        alignment = getContext().getTypeAlignInChars(type).getQuantity();
       cvr = 0; // qualifiers don't recursively apply to referencee
     }
   }
@@ -1887,7 +1902,6 @@
   if (field->hasAttr<AnnotateAttr>())
     addr = EmitFieldAnnotations(field, addr);
 
-  unsigned alignment = getContext().getDeclAlign(field).getQuantity();
   LValue LV = MakeAddrLValue(addr, type, alignment);
   LV.getQuals().addCVRQualifiers(cvr);
 

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=144745&r1=144744&r2=144745&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Nov 15 18:42:57 2011
@@ -1541,6 +1541,15 @@
     return LValue::MakeAddr(V, T, Alignment, getContext(),
                             CGM.getTBAAInfo(T));
   }
+  LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T) {
+    unsigned Alignment;
+    if (T->isIncompleteType())
+      Alignment = 0;
+    else
+      Alignment = getContext().getTypeAlignInChars(T).getQuantity();
+    return LValue::MakeAddr(V, T, Alignment, getContext(),
+                            CGM.getTBAAInfo(T));
+  }
 
   /// CreateTempAlloca - This creates a alloca and inserts it into the entry
   /// block. The caller is responsible for setting an appropriate alignment on

Modified: cfe/trunk/test/CodeGenCXX/references.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/references.cpp?rev=144745&r1=144744&r2=144745&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/references.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/references.cpp Tue Nov 15 18:42:57 2011
@@ -1,10 +1,16 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin -verify -emit-llvm -o - %s | FileCheck %s
 void t1() {
+  // CHECK: define void @_Z2t1v
+  // CHECK: [[REFLOAD:%.*]] = load i32** @a, align 8
+  // CHECK: load i32* [[REFLOAD]], align 4
   extern int& a;
   int b = a; 
 }
 
 void t2(int& a) {
+  // CHECK: define void @_Z2t2Ri
+  // CHECK: [[REFLOAD2:%.*]] = load i32** {{.*}}, align 8
+  // CHECK: load i32* [[REFLOAD2]], align 4
   int b = a;
 }
 
@@ -297,3 +303,11 @@
     // CHECK-NEXT: ret void
   }
 }
+
+namespace N6 {
+  extern struct x {char& x;}y;
+  int a() { return y.x; }
+  // CHECK: define i32 @_ZN2N61aEv
+  // CHECK: [[REFLOAD3:%.*]] = load i8** getelementptr inbounds (%"struct.N6::x"* @_ZN2N61yE, i32 0, i32 0), align 8
+  // CHECK: %0 = load i8* [[REFLOAD3]], align 1
+}





More information about the cfe-commits mailing list