diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2986,6 +2986,8 @@ "redeclaration has different alignment requirement (%1 vs %0)">; def err_alignas_underaligned : Error< "requested alignment is less than minimum alignment of %1 for type %0">; +def warn_aligned_attr_underaligned : Warning, + InGroup; def err_attribute_sizeless_type : Error< "%0 attribute cannot be applied to sizeless type %1">; def err_attribute_argument_n_type : Error< diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -4063,12 +4063,12 @@ return; } - if (Context.getTargetInfo().isTLSSupported()) { + const auto *VD = dyn_cast(D); + if (VD && Context.getTargetInfo().isTLSSupported()) { unsigned MaxTLSAlign = Context.toCharUnitsFromBits(Context.getTargetInfo().getMaxTLSAlign()) .getQuantity(); - const auto *VD = dyn_cast(D); - if (MaxTLSAlign && AlignVal > MaxTLSAlign && VD && + if (MaxTLSAlign && AlignVal > MaxTLSAlign && VD->getTLSKind() != VarDecl::TLS_None) { Diag(VD->getLocation(), diag::err_tls_var_aligned_over_maximum) << (unsigned)AlignVal << VD << MaxTLSAlign; @@ -4076,6 +4076,17 @@ } } + // On AIX, an aligned attribute can not decrease the alignment when applied + // to a variable declaration with vector type. + if (VD && Context.getTargetInfo().getTriple().isOSAIX()) { + const Type *Ty = VD->getType().getTypePtr(); + if (Ty->isVectorType() && AlignVal < 16) { + Diag(VD->getLocation(), diag::warn_aligned_attr_underaligned) + << VD->getType() << 16; + return; + } + } + AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, true, ICE.get()); AA->setPackExpansion(IsPackExpansion); D->addAttr(AA); diff --git a/clang/test/CodeGen/aix-vector-attr-aligned.c b/clang/test/CodeGen/aix-vector-attr-aligned.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/aix-vector-attr-aligned.c @@ -0,0 +1,33 @@ +// REQUIRES: powerpc-registered-target +// RUN: %clang_cc1 -triple powerpc-unknown-aix -target-feature +altivec -target-cpu pwr7 -emit-llvm -o - %s | \ +// RUN: FileCheck %s +// RUN: %clang_cc1 -triple powerpc64-unknown-aix -target-feature +altivec -target-cpu pwr7 -emit-llvm -o - %s | \ +// RUN: FileCheck %s + +typedef vector int __attribute__((aligned(8))) UnderAlignedVI; + +vector int g32 __attribute__((aligned(32))); +vector int g8 __attribute__((aligned(8))); +UnderAlignedVI TypedefedGlobal; + +int escape(vector int*); + +int local32(void) { + vector int l32 __attribute__((aligned(32))); + return escape(&l32); +} + +int local8(void) { + vector int l8 __attribute__((aligned(8))); + return escape(&l8); +} + +// CHECK: @g32 = global <4 x i32> zeroinitializer, align 32 +// CHECK: @g8 = global <4 x i32> zeroinitializer, align 16 +// CHECK: @TypedefedGlobal = global <4 x i32> zeroinitializer, align 8 + +// CHECK-LABEL: @local32 +// CHECK: %l32 = alloca <4 x i32>, align 32 +// +// CHECK-LABEL: @local8 +// CHECK: %l8 = alloca <4 x i32>, align 16 diff --git a/clang/test/Sema/aix-attr-aligned-vector-warn.c b/clang/test/Sema/aix-attr-aligned-vector-warn.c new file mode 100644 --- /dev/null +++ b/clang/test/Sema/aix-attr-aligned-vector-warn.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -triple powerpc64-unknown-aix -target-feature +altivec -target-cpu pwr7 -verify -fsyntax-only %s +// RUN: %clang_cc1 -triple powerpc-unknown-aix -target-feature +altivec -target-cpu pwr7 -verify -fsyntax-only %s + +int escape(vector int*); + +typedef vector int __attribute__((aligned(8))) UnderAlignedVI; +UnderAlignedVI TypedefedGlobal; + +vector int V __attribute__((aligned(8))); // expected-warning {{requested alignment is less than minimum alignment of 16 for type '__vector int' (vector of 4 'int' values)}} + +int localTypedefed(void) { + UnderAlignedVI TypedefedLocal; + return escape(&TypedefedLocal); // expected-warning {{passing 8-byte aligned argument to 16-byte aligned parameter 1 of 'escape' may result in an unaligned pointer access}} +}