[cfe-commits] r111726 - in /cfe/trunk: lib/CodeGen/CGExpr.cpp lib/CodeGen/CodeGenFunction.h test/CodeGen/address-space-field1.c test/CodeGen/packed-structure.c

Daniel Dunbar daniel at zuster.org
Fri Aug 20 21:20:22 PDT 2010


Author: ddunbar
Date: Fri Aug 20 23:20:22 2010
New Revision: 111726

URL: http://llvm.org/viewvc/llvm-project?rev=111726&view=rev
Log:
IRgen: Set the alignment correctly when creating LValue for a decls.
 - Fixes PR5598.
 - Review appreciated.

Added:
    cfe/trunk/test/CodeGen/packed-structure.c
Modified:
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/test/CodeGen/address-space-field1.c

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=111726&r1=111725&r2=111726&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Fri Aug 20 23:20:22 2010
@@ -1118,7 +1118,8 @@
   llvm::Value *V = CGF.CGM.GetAddrOfGlobalVar(VD);
   if (VD->getType()->isReferenceType())
     V = CGF.Builder.CreateLoad(V, "tmp");
-  LValue LV = CGF.MakeAddrLValue(V, E->getType());
+  unsigned Alignment = CGF.getContext().getDeclAlign(VD).getQuantity();
+  LValue LV = CGF.MakeAddrLValue(V, E->getType(), Alignment);
   setObjCGCLValueClass(CGF.getContext(), E, LV);
   return LV;
 }
@@ -1138,17 +1139,18 @@
       V = CGF.Builder.CreateBitCast(V, CGF.ConvertType(NoProtoType), "tmp");
     }
   }
-  return CGF.MakeAddrLValue(V, E->getType());
+  unsigned Alignment = CGF.getContext().getDeclAlign(FD).getQuantity();
+  return CGF.MakeAddrLValue(V, E->getType(), Alignment);
 }
 
 LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
   const NamedDecl *ND = E->getDecl();
+  unsigned Alignment = CGF.getContext().getDeclAlign(ND).getQuantity();
 
   if (ND->hasAttr<WeakRefAttr>()) {
     const ValueDecl* VD = cast<ValueDecl>(ND);
     llvm::Constant *Aliasee = CGM.GetWeakRefReference(VD);
-
-    return MakeAddrLValue(Aliasee, E->getType());
+    return MakeAddrLValue(Aliasee, E->getType(), Alignment);
   }
 
   if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
@@ -1174,7 +1176,7 @@
     if (VD->getType()->isReferenceType())
       V = Builder.CreateLoad(V, "tmp");
 
-    LValue LV = MakeAddrLValue(V, E->getType());
+    LValue LV = MakeAddrLValue(V, E->getType(), Alignment);
     if (NonGCable) {
       LV.getQuals().removeObjCGCAttr();
       LV.setNonGC(true);
@@ -1190,7 +1192,7 @@
   if (E->getQualifier()) {
     const FieldDecl *FD = cast<FieldDecl>(ND);
     llvm::Value *V = CGM.EmitPointerToDataMember(FD);
-    return MakeAddrLValue(V, FD->getType());
+    return MakeAddrLValue(V, FD->getType(), Alignment);
   }
   
   assert(false && "Unhandled DeclRefExpr");
@@ -1201,7 +1203,9 @@
 }
 
 LValue CodeGenFunction::EmitBlockDeclRefLValue(const BlockDeclRefExpr *E) {
-  return MakeAddrLValue(GetAddrOfBlockDecl(E), E->getType());
+  unsigned Alignment =
+    CGF.getContext().getDeclAlign(E->getDecl()).getQuantity();
+  return MakeAddrLValue(GetAddrOfBlockDecl(E), E->getType(), Alignment);
 }
 
 LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
@@ -1637,7 +1641,8 @@
   if (Field->getType()->isReferenceType())
     V = Builder.CreateLoad(V, "tmp");
 
-  LValue LV = MakeAddrLValue(V, Field->getType());
+  unsigned Alignment = getContext().getDeclAlign(Field).getQuantity();
+  LValue LV = MakeAddrLValue(V, Field->getType(), Alignment);
   LV.getQuals().addCVRQualifiers(CVRQualifiers);
 
   // __weak attribute on a field is ignored.
@@ -1663,7 +1668,8 @@
 
   assert(!FieldType.getObjCGCAttr() && "fields cannot have GC attrs");
 
-  return MakeAddrLValue(V, FieldType);
+  unsigned Alignment = getContext().getDeclAlign(Field).getQuantity();
+  return MakeAddrLValue(V, FieldType, Alignment);
 }
 
 LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr* E){

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=111726&r1=111725&r2=111726&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Fri Aug 20 23:20:22 2010
@@ -969,8 +969,8 @@
   //                                  Helpers
   //===--------------------------------------------------------------------===//
 
-  LValue MakeAddrLValue(llvm::Value *V, QualType T) {
-    return LValue::MakeAddr(V, T, 0, getContext());
+  LValue MakeAddrLValue(llvm::Value *V, QualType T, unsigned Alignment = 0) {
+    return LValue::MakeAddr(V, T, Alignment, getContext());
   }
 
   /// CreateTempAlloca - This creates a alloca and inserts it into the entry

Modified: cfe/trunk/test/CodeGen/address-space-field1.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/address-space-field1.c?rev=111726&r1=111725&r2=111726&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/address-space-field1.c (original)
+++ cfe/trunk/test/CodeGen/address-space-field1.c Fri Aug 20 23:20:22 2010
@@ -5,18 +5,18 @@
 // CHECK:  [[p2addr:%.*]] = alloca %struct.S addrspace(2)*
 // CHECK:  store %struct.S addrspace(1)* %p1, %struct.S addrspace(1)** [[p1addr]]
 // CHECK:  store %struct.S addrspace(2)* %p2, %struct.S addrspace(2)** [[p2addr]]
-// CHECK:  [[t0:%.*]] = load %struct.S addrspace(2)** [[p2addr]]   ; <%struct.S addrspace(2)*> [#uses=1]
+// CHECK:  [[t0:%.*]] = load %struct.S addrspace(2)** [[p2addr]], align 8   ; <%struct.S addrspace(2)*> [#uses=1]
 // CHECK:  [[t1:%.*]] = getelementptr inbounds %struct.S addrspace(2)* [[t0]], i32 0, i32 1 ; <i32 addrspace(2)*> [#uses=1]
-// CHECK:  [[t2:%.*]] = load i32 addrspace(2)* [[t1]]            ; <i32> [#uses=1]
-// CHECK:  [[t3:%.*]] = load %struct.S addrspace(1)** [[p1addr]]  ; <%struct.S addrspace(1)*> [#uses=1]
+// CHECK:  [[t2:%.*]] = load i32 addrspace(2)* [[t1]], align 4            ; <i32> [#uses=1]
+// CHECK:  [[t3:%.*]] = load %struct.S addrspace(1)** [[p1addr]], align 8  ; <%struct.S addrspace(1)*> [#uses=1]
 // CHECK:  [[t4:%.*]] = getelementptr inbounds %struct.S addrspace(1)* [[t3]], i32 0, i32 0 ; <i32 addrspace(1)*> [#uses=1]
-// CHECK:  store i32 [[t2]], i32 addrspace(1)* [[t4]]
-// CHECK:  [[t5:%.*]] = load %struct.S addrspace(2)** [[p2addr]]  ; <%struct.S addrspace(2)*> [#uses=1]
+// CHECK:  store i32 [[t2]], i32 addrspace(1)* [[t4]], align 4
+// CHECK:  [[t5:%.*]] = load %struct.S addrspace(2)** [[p2addr]], align 8  ; <%struct.S addrspace(2)*> [#uses=1]
 // CHECK:  [[t6:%.*]] = getelementptr inbounds %struct.S addrspace(2)* [[t5]], i32 0, i32 0 ; <i32 addrspace(2)*> [#uses=1]
-// CHECK:  [[t7:%.*]] = load i32 addrspace(2)* [[t6]]            ; <i32> [#uses=1]
-// CHECK:  [[t8:%.*]] = load %struct.S addrspace(1)** [[p1addr]]  ; <%struct.S addrspace(1)*> [#uses=1]
+// CHECK:  [[t7:%.*]] = load i32 addrspace(2)* [[t6]], align 4            ; <i32> [#uses=1]
+// CHECK:  [[t8:%.*]] = load %struct.S addrspace(1)** [[p1addr]], align 8  ; <%struct.S addrspace(1)*> [#uses=1]
 // CHECK:  [[t9:%.*]] = getelementptr inbounds %struct.S addrspace(1)* [[t8]], i32 0, i32 1 ; <i32 addrspace(1)*> [#uses=1]
-// CHECK:  store i32 [[t7]], i32 addrspace(1)* [[t9]]
+// CHECK:  store i32 [[t7]], i32 addrspace(1)* [[t9]], align 4
 // CHECK:  ret void
 // CHECK:}
 

Added: cfe/trunk/test/CodeGen/packed-structure.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/packed-structure.c?rev=111726&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/packed-structure.c (added)
+++ cfe/trunk/test/CodeGen/packed-structure.c Fri Aug 20 23:20:22 2010
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -triple x86_64 -emit-llvm -o - %s | opt -S -strip -o %t
+// RUX: llvm-gcc -flto -S -O3 -o %t %s
+// RUN: FileCheck --check-prefix=CHECK-GLOBAL < %t %s
+// RUN: FileCheck --check-prefix=CHECK-FUNCTIONS < %t %s
+
+struct s0 {
+  int x;
+  int y __attribute__((packed));
+};
+
+// CHECK-GLOBAL: @s0_align_x = global i32 4
+
+// FIXME: This should be 1 to match gcc. PR7951.
+// CHECK-GLOBAL: @s0_align_y = global i32 4
+
+// CHECK-GLOBAL: @s0_align = global i32 4
+int s0_align_x = __alignof(((struct s0*)0)->x);
+int s0_align_y = __alignof(((struct s0*)0)->y);
+int s0_align   = __alignof(struct s0);
+
+// CHECK-FUNCTIONS: define i32 @s0_load_x
+// CHECK-FUNCTIONS: [[s0_load_x:%.*]] = load i32* {{.*}}, align 4
+// CHECK-FUNCTIONS: ret i32 [[s0_load_x]]
+int s0_load_x(struct s0 *a) { return a->x; }
+// FIXME: This seems like it should be align 1. This is actually something which
+// has changed in llvm-gcc recently, previously both x and y would be loaded
+// with align 1 (in 2363.1 at least).
+//
+// CHECK-FUNCTIONS: define i32 @s0_load_y
+// CHECK-FUNCTIONS: [[s0_load_y:%.*]] = load i32* {{.*}}, align 4
+// CHECK-FUNCTIONS: ret i32 [[s0_load_y]]
+int s0_load_y(struct s0 *a) { return a->y; }
+// CHECK-FUNCTIONS: define void @s0_copy
+// CHECK-FUNCTIONS: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* {{.*}}, i64 8, i32 4, i1 false)
+void s0_copy(struct s0 *a, struct s0 *b) { *b = *a; }
+
+//
+
+struct s1 {
+  int x;
+  int y;
+} __attribute__((packed));
+
+// CHECK-GLOBAL: @s1_align_x = global i32 1
+// CHECK-GLOBAL: @s1_align_y = global i32 1
+// CHECK-GLOBAL: @s1_align = global i32 1
+int s1_align_x = __alignof(((struct s1*)0)->x);
+int s1_align_y = __alignof(((struct s1*)0)->y);
+int s1_align   = __alignof(struct s1);
+
+// CHECK-FUNCTIONS: define i32 @s1_load_x
+// CHECK-FUNCTIONS: [[s1_load_x:%.*]] = load i32* {{.*}}, align 1
+// CHECK-FUNCTIONS: ret i32 [[s1_load_x]]
+int s1_load_x(struct s1 *a) { return a->x; }
+// CHECK-FUNCTIONS: define i32 @s1_load_y
+// CHECK-FUNCTIONS: [[s1_load_y:%.*]] = load i32* {{.*}}, align 1
+// CHECK-FUNCTIONS: ret i32 [[s1_load_y]]
+int s1_load_y(struct s1 *a) { return a->y; }
+// CHECK-FUNCTIONS: define void @s1_copy
+// CHECK-FUNCTIONS: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* {{.*}}, i64 8, i32 1, i1 false)
+void s1_copy(struct s1 *a, struct s1 *b) { *b = *a; }
+
+//
+
+#pragma pack(push,2)
+struct s2 {
+  int x;
+  int y;
+};
+#pragma pack(pop)
+
+// CHECK-GLOBAL: @s2_align_x = global i32 2
+// CHECK-GLOBAL: @s2_align_y = global i32 2
+// CHECK-GLOBAL: @s2_align = global i32 2
+int s2_align_x = __alignof(((struct s2*)0)->x);
+int s2_align_y = __alignof(((struct s2*)0)->y);
+int s2_align   = __alignof(struct s2);
+
+// CHECK-FUNCTIONS: define i32 @s2_load_x
+// CHECK-FUNCTIONS: [[s2_load_y:%.*]] = load i32* {{.*}}, align 2
+// CHECK-FUNCTIONS: ret i32 [[s2_load_y]]
+int s2_load_x(struct s2 *a) { return a->x; }
+// CHECK-FUNCTIONS: define i32 @s2_load_y
+// CHECK-FUNCTIONS: [[s2_load_y:%.*]] = load i32* {{.*}}, align 2
+// CHECK-FUNCTIONS: ret i32 [[s2_load_y]]
+int s2_load_y(struct s2 *a) { return a->y; }
+// CHECK-FUNCTIONS: define void @s2_copy
+// CHECK-FUNCTIONS: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* {{.*}}, i64 8, i32 2, i1 false)
+void s2_copy(struct s2 *a, struct s2 *b) { *b = *a; }





More information about the cfe-commits mailing list