[PATCH] Make getPreferredTypeAlign respect alignments specified with an aligned attribute on a typedef

Stephan Tolksdorf st at quanttec.com
Wed Feb 12 13:21:26 PST 2014


On 14-02-12 20:45, David Majnemer wrote:
> This looks like the right place to fix the bug.
>
> Three comments:
> - The '*' for pointer types should be on the right side.
> - AlignedAttr::getMaxAlignment() isn't always super fast but I guess
> such typedefs are rare.  An argument could be made that getTypeInfoImpl
> should return a struct containing the size, alignment and whether or not
> the type has an explicit alignment.  Then, getPreferredTypeAlign() could
> take advantage of it.
> - Both of your tests in CodeGen/alignment.c already pass without your patch.

Thanks a lot for the review!

I've moved the '*' to the right and split off the alignment.c changes 
into a separate patch.

I suppose that typedefs with attributes are so rare that the overhead of 
the new getMaxAlignment call should be minimal.

Please commit the patches if you think they are ready. (I don't have 
commit access.)

Thanks again,
   Stephan

-------------- next part --------------
Subject: [PATCH] Make getPreferredTypeAlign respect alignments specified with
 an aligned attribute on a typedef

---
 lib/AST/ASTContext.cpp   | 5 +++++
 test/Sema/attr-aligned.c | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 6af79cd..8413342 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1762,12 +1762,17 @@ CharUnits ASTContext::getTypeAlignInChars(const Type *T) const {
 unsigned ASTContext::getPreferredTypeAlign(const Type *T) const {
   unsigned ABIAlign = getTypeAlign(T);
 
   if (Target->getTriple().getArch() == llvm::Triple::xcore)
     return ABIAlign;  // Never overalign on XCore.
 
+  // Don't change alignments specified with an aligned attribute on a typedef.
+  if (const TypedefType *TT = T->getAs<TypedefType>())
+    if (TT->getDecl()->getMaxAlignment())
+      return ABIAlign;
+
   // Double and long long should be naturally aligned if possible.
   if (const ComplexType* CT = T->getAs<ComplexType>())
     T = CT->getElementType().getTypePtr();
   if (T->isSpecificBuiltinType(BuiltinType::Double) ||
       T->isSpecificBuiltinType(BuiltinType::LongLong) ||
       T->isSpecificBuiltinType(BuiltinType::ULongLong))
diff --git a/test/Sema/attr-aligned.c b/test/Sema/attr-aligned.c
index c094ff1..22158e9 100644
--- a/test/Sema/attr-aligned.c
+++ b/test/Sema/attr-aligned.c
@@ -17,12 +17,15 @@ char a = 0;
 
 char a0[__alignof__(ueber_aligned_char) == 8? 1 : -1] = { 0 };
 char a1[__alignof__(struct struct_with_ueber_char) == 8? 1 : -1] = { 0 };
 char a2[__alignof__(a) == 1? : -1] = { 0 };
 char a3[sizeof(a) == 1? : -1] = { 0 };
 
+typedef long long __attribute__((aligned(1))) underaligned_longlong;
+char a4[__alignof__(underaligned_longlong) == 1 ?: -1] = {0};
+
 // rdar://problem/8335865
 int b __attribute__((aligned(2)));
 char b1[__alignof__(b) == 2 ?: -1] = {0};
 
 struct C { int member __attribute__((aligned(2))); } c;
 char c1[__alignof__(c) == 4 ?: -1] = {0};
-- 

-------------- next part --------------
Subject: [PATCH] Add an additional test to CodeGen/alignment.c covering an
 underaligned long long typedef

Given the precedent of special handling of long long in getPreferredTypeAlign I thought it might be prudent to double check that the codegen respects the aligned attribute also for long long typedefs.
---
 test/CodeGen/alignment.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/test/CodeGen/alignment.c b/test/CodeGen/alignment.c
index 04d6aac..091bc45 100644
--- a/test/CodeGen/alignment.c
+++ b/test/CodeGen/alignment.c
@@ -24,12 +24,29 @@ int test1a(myint *p) {
 }
 // CHECK: @test1a(
 // CHECK: load i32* {{.*}}, align 1
 // CHECK: ret i32
 
 
+typedef long long int myllint __attribute__((aligned(1)));
+
+void test1b(myllint *p) {
+  *p = 0;
+}
+// CHECK: @test1b(
+// CHECK: store i64 0, i64* {{.*}}, align 1
+// CHECK: ret void
+
+long long int test1c(myllint *p) {
+  return *p;
+}
+// CHECK: @test1c(
+// CHECK: load i64* {{.*}}, align 1
+// CHECK: ret i64
+
+
 // PR5279 - Reduced alignment on typedef.
 typedef float __attribute__((vector_size(16), aligned(4))) packedfloat4;
 
 void test2(packedfloat4 *p) {
   *p = (packedfloat4) { 3.2f, 2.3f, 0.1f, 0.0f };
 }
-- 



More information about the cfe-commits mailing list