| Hi John, Here is the revised patch. |
Index: include/clang/AST/ASTContext.h
===================================================================
--- include/clang/AST/ASTContext.h (revision 214520)
+++ include/clang/AST/ASTContext.h (working copy)
@@ -78,9 +78,13 @@
uint64_t Width;
unsigned Align;
bool AlignIsRequired : 1;
- TypeInfo() : Width(0), Align(0), AlignIsRequired(false) {}
- TypeInfo(uint64_t Width, unsigned Align, bool AlignIsRequired)
- : Width(Width), Align(Align), AlignIsRequired(AlignIsRequired) {}
+ bool HasAlignAttribute : 1;
+ TypeInfo() : Width(0), Align(0), AlignIsRequired(false),
+ HasAlignAttribute(false) {}
+ TypeInfo(uint64_t Width, unsigned Align, bool AlignIsRequired,
+ bool HasAlignAttribute)
+ : Width(Width), Align(Align), AlignIsRequired(AlignIsRequired),
+ HasAlignAttribute(HasAlignAttribute) {}
};
/// \brief Holds long-lived AST nodes (such as types and decls) that can be
@@ -1666,6 +1670,10 @@
/// alignment attribute.
bool isAlignmentRequired(const Type *T) const;
bool isAlignmentRequired(QualType T) const;
+
+ /// \brief Determine if type has an explicit align attribute.
+ bool hasAlignAttribute(const Type *T) const;
+ bool hasAlignAttribute(QualType T) const;
/// \brief Return the "preferred" alignment of the specified type \p T for
/// the current target, in bits.
Index: include/clang/Basic/LangOptions.def
===================================================================
--- include/clang/Basic/LangOptions.def (revision 214520)
+++ include/clang/Basic/LangOptions.def (working copy)
@@ -106,6 +106,8 @@
LANGOPT(Static , 1, 0, "__STATIC__ predefined macro (as opposed to
__DYNAMIC__)")
VALUE_LANGOPT(PackStruct , 32, 0,
"default struct packing maximum alignment")
+VALUE_LANGOPT(MaxTypeAlign , 32, 0,
+ "default maximum alignment for types")
VALUE_LANGOPT(PICLevel , 2, 0, "__PIC__ level")
VALUE_LANGOPT(PIELevel , 2, 0, "__PIE__ level")
LANGOPT(GNUInline , 1, 0, "GNU inline semantics")
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td (revision 214520)
+++ include/clang/Driver/Options.td (working copy)
@@ -793,6 +793,9 @@
def fno_pack_struct : Flag<["-"], "fno-pack-struct">, Group<f_Group>;
def fpack_struct_EQ : Joined<["-"], "fpack-struct=">, Group<f_Group>,
Flags<[CC1Option]>,
HelpText<"Specify the default maximum struct packing alignment">;
+def fmax_type_align_EQ : Joined<["-"], "fmax-type-align=">, Group<f_Group>,
Flags<[CC1Option]>,
+ HelpText<"Specify the default maximum alignment for types">;
+def fno_max_type_align : Flag<["-"], "fno-max-type-align">, Group<f_Group>;
def fpascal_strings : Flag<["-"], "fpascal-strings">, Group<f_Group>,
Flags<[CC1Option]>,
HelpText<"Recognize and construct Pascal-style string literals">;
def fpcc_struct_return : Flag<["-"], "fpcc-struct-return">, Group<f_Group>,
Flags<[CC1Option]>,
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp (revision 214520)
+++ lib/AST/ASTContext.cpp (working copy)
@@ -1431,6 +1431,14 @@
return isAlignmentRequired(T.getTypePtr());
}
+bool ASTContext::hasAlignAttribute(const Type *T) const {
+ return getTypeInfo(T).HasAlignAttribute;
+}
+
+bool ASTContext::hasAlignAttribute(QualType T) const {
+ return hasAlignAttribute(T.getTypePtr());
+}
+
TypeInfo ASTContext::getTypeInfo(const Type *T) const {
TypeInfoMap::iterator I = MemoizedTypeInfo.find(T);
if (I != MemoizedTypeInfo.end())
@@ -1452,6 +1460,7 @@
uint64_t Width = 0;
unsigned Align = 8;
bool AlignIsRequired = false;
+ bool HasAlignAttribute = false;
switch (T->getTypeClass()) {
#define TYPE(Class, Base)
#define ABSTRACT_TYPE(Class, Base)
@@ -1701,6 +1710,8 @@
case Type::Typedef: {
const TypedefNameDecl *Typedef = cast<TypedefType>(T)->getDecl();
TypeInfo Info = getTypeInfo(Typedef->getUnderlyingType().getTypePtr());
+ HasAlignAttribute =
+ (Typedef->hasAttr<AlignedAttr>() || Info.HasAlignAttribute);
// If the typedef has an aligned attribute on it, it overrides any computed
// alignment we have. This violates the GCC documentation (which says that
// attribute(aligned) can only round up) but matches its implementation.
@@ -1742,7 +1753,7 @@
}
assert(llvm::isPowerOf2_32(Align) && "Alignment must be power of 2");
- return TypeInfo(Width, Align, AlignIsRequired);
+ return TypeInfo(Width, Align, AlignIsRequired, HasAlignAttribute);
}
/// toCharUnitsFromBits - Convert a size in bits to a size in characters.
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp (revision 214520)
+++ lib/CodeGen/CGExpr.cpp (working copy)
@@ -761,6 +761,18 @@
LV = EmitArraySubscriptExpr(cast<ArraySubscriptExpr>(E), /*Accessed*/true);
else
LV = EmitLValue(E);
+ ASTContext &Context = CGM.getContext();
+ if (const UnaryOperator *UOPE = dyn_cast<UnaryOperator>(E))
+ if (UOPE->getOpcode() == UO_Deref) {
+ unsigned MaxAlign = Context.getLangOpts().MaxTypeAlign;
+ QualType T = E->getType();
+ if (MaxAlign && !Context.hasAlignAttribute(T)) {
+ CharUnits Alignment = Context.getTypeAlignInChars(T);
+ if (Alignment.getQuantity() > MaxAlign)
+ LV.setAlignment(CharUnits::fromQuantity(MaxAlign));
+ }
+ }
+
if (!isa<DeclRefExpr>(E) && !LV.isBitField() && LV.isSimple())
EmitTypeCheck(TCK, E->getExprLoc(), LV.getAddress(),
E->getType(), LV.getAlignment());
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp (revision 214520)
+++ lib/Driver/Tools.cpp (working copy)
@@ -4111,6 +4111,21 @@
CmdArgs.push_back("-fpack-struct=1");
}
+ // Handle -fmax-type-align=N and -fno-type-align
+ bool SkipMaxTypeAlign = Args.hasArg(options::OPT_fno_max_type_align);
+ if (Arg *A = Args.getLastArg(options::OPT_fmax_type_align_EQ)) {
+ if (!SkipMaxTypeAlign) {
+ std::string MaxTypeAlignStr = "-fmax-type-align=";
+ MaxTypeAlignStr += A->getValue();
+ CmdArgs.push_back(Args.MakeArgString(MaxTypeAlignStr));
+ }
+ } else if (getToolChain().getTriple().isOSDarwin()) {
+ if (!SkipMaxTypeAlign) {
+ std::string MaxTypeAlignStr = "-fmax-type-align=16";
+ CmdArgs.push_back(Args.MakeArgString(MaxTypeAlignStr));
+ }
+ }
+
if (KernelOrKext || isNoCommonDefault(getToolChain().getTriple())) {
if (!Args.hasArg(options::OPT_fcommon))
CmdArgs.push_back("-fno-common");
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp (revision 214520)
+++ lib/Frontend/CompilerInvocation.cpp (working copy)
@@ -1475,6 +1475,7 @@
Args.hasArg(OPT_fencode_extended_block_signature);
Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
Opts.PackStruct = getLastArgIntValue(Args, OPT_fpack_struct_EQ, 0, Diags);
+ Opts.MaxTypeAlign = getLastArgIntValue(Args, OPT_fmax_type_align_EQ, 0,
Diags);
Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
Opts.PIELevel = getLastArgIntValue(Args, OPT_pie_level, 0, Diags);
Opts.Static = Args.hasArg(OPT_static_define);
Index: test/CodeGenCXX/align-avx-complete-objects.cpp
===================================================================
--- test/CodeGenCXX/align-avx-complete-objects.cpp (revision 0)
+++ test/CodeGenCXX/align-avx-complete-objects.cpp (working copy)
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -x c++ %s -O0 -triple=x86_64-apple-darwin -target-feature
+avx2 -fmax-type-align=16 -emit-llvm -o - -Werror | FileCheck %s
+// rdar://16254558
+
+typedef float AVX2Float __attribute__((__vector_size__(32)));
+
+
+volatile float TestAlign(void)
+{
+ volatile AVX2Float *p = new AVX2Float;
+ *p = *p;
+ AVX2Float r = *p;
+ return r[0];
+}
+
+// CHECK: [[R:%.*]] = alloca <8 x float>, align 32
+// CHECK-NEXT: [[CALL:%.*]] = call noalias i8* @_Znwm(i64 32)
+// CHECK-NEXT: [[ZERO:%.*]] = bitcast i8* [[CALL]] to <8 x float>*
+// CHECK-NEXT: store <8 x float>* [[ZERO]], <8 x float>** [[P:%.*]], align 8
+// CHECK-NEXT: [[ONE:%.*]] = load <8 x float>** [[P]], align 8
+// CHECK-NEXT: [[TWO:%.*]] = load volatile <8 x float>* [[ONE]], align 16
+// CHECK-NEXT: [[THREE:%.*]] = load <8 x float>** [[P]], align 8
+// CHECK-NEXT: store volatile <8 x float> [[TWO]], <8 x float>* [[THREE]],
align 16
+// CHECK-NEXT: [[FOUR:%.*]] = load <8 x float>** [[P]], align 8
+// CHECK-NEXT: [[FIVE:%.*]] = load volatile <8 x float>* [[FOUR]], align 16
+// CHECK-NEXT: store <8 x float> [[FIVE]], <8 x float>* [[R]], align 32
+// CHECK-NEXT: [[SIX:%.*]] = load <8 x float>* [[R]], align 32
+// CHECK-NEXT: [[VECEXT:%.*]] = extractelement <8 x float> [[SIX]], i32 0
+// CHECK-NEXT: ret float [[VECEXT]]
+
+typedef float AVX2Float_Explicitly_aligned
__attribute__((__vector_size__(32))) __attribute__((aligned (32)));
+
+typedef AVX2Float_Explicitly_aligned AVX2Float_indirect;
+
+typedef AVX2Float_indirect AVX2Float_use_existing_align;
+
+volatile float TestAlign2(void)
+{
+ volatile AVX2Float_use_existing_align *p = new
AVX2Float_use_existing_align;
+ *p = *p;
+ AVX2Float_use_existing_align r = *p;
+ return r[0];
+}
+
+// CHECK: [[R:%.*]] = alloca <8 x float>, align 32
+// CHECK-NEXT: [[CALL:%.*]] = call noalias i8* @_Znwm(i64 32)
+// CHECK-NEXT: [[ZERO:%.*]] = bitcast i8* [[CALL]] to <8 x float>*
+// CHECK-NEXT: store <8 x float>* [[ZERO]], <8 x float>** [[P:%.*]], align 8
+// CHECK-NEXT: [[ONE:%.*]] = load <8 x float>** [[P]], align 8
+// CHECK-NEXT: [[TWO:%.*]] = load volatile <8 x float>* [[ONE]], align 32
+// CHECK-NEXT: [[THREE:%.*]] = load <8 x float>** [[P]], align 8
+// CHECK-NEXT: store volatile <8 x float> [[TWO]], <8 x float>* [[THREE]],
align 32
+// CHECK-NEXT: [[FOUR:%.*]] = load <8 x float>** [[P]], align 8
+// CHECK-NEXT: [[FIVE:%.*]] = load volatile <8 x float>* [[FOUR]], align 32
+// CHECK-NEXT: store <8 x float> [[FIVE]], <8 x float>* [[R]], align 32
+// CHECK-NEXT: [[SIX:%.*]] = load <8 x float>* [[R]], align 32
+// CHECK-NEXT: [[VECEXT:%.*]] = extractelement <8 x float> [[SIX]], i32 0
+// CHECK-NEXT: ret float [[VECEXT]]
Index: test/Driver/darwin-max-type-align.c
===================================================================
--- test/Driver/darwin-max-type-align.c (revision 0)
+++ test/Driver/darwin-max-type-align.c (working copy)
@@ -0,0 +1,15 @@
+// Check the -fmax-type-align=N flag
+// rdar://16254558
+//
+// RUN: %clang -no-canonical-prefixes -target x86_64-apple-macosx10.7.0 %s -o
- -### 2>&1 | \
+// RUN: FileCheck -check-prefix=TEST0 %s
+// TEST0: -fmax-type-align=16
+// RUN: %clang -no-canonical-prefixes -fmax-type-align=32 -target
x86_64-apple-macosx10.7.0 %s -o - -### 2>&1 | \
+// RUN: FileCheck -check-prefix=TEST1 %s
+// TEST1: -fmax-type-align=32
+// RUN: %clang -no-canonical-prefixes -fmax-type-align=32 -fno-max-type-align
-target x86_64-apple-macosx10.7.0 %s -o - -### 2>&1 | \
+// RUN: FileCheck -check-prefix=TEST2 %s
+// TEST2-NOT: -fmax-type-align
+// RUN: %clang -no-canonical-prefixes -fno-max-type-align -target
x86_64-apple-macosx10.7.0 %s -o - -### 2>&1 | \
+// RUN: FileCheck -check-prefix=TEST3 %s
+// TEST3-NOT: -fmax-type-align
Index: test/Driver/rewrite-legacy-objc.m
===================================================================
--- test/Driver/rewrite-legacy-objc.m (revision 214520)
+++ test/Driver/rewrite-legacy-objc.m (working copy)
@@ -3,11 +3,11 @@
// TEST0: clang{{.*}}" "-cc1"
// TEST0: "-rewrite-objc"
// FIXME: CHECK-NOT is broken somehow, it doesn't work here. Check adjacency
instead.
-// TEST0: "-fmessage-length" "0" "-stack-protector" "1" "-mstackrealign"
"-fblocks" "-fobjc-runtime=macosx-fragile" "-fencode-extended-block-signature"
"-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions"
"-fdiagnostics-show-option"
+// TEST0: "-fmessage-length" "0" "-stack-protector" "1" "-mstackrealign"
"-fblocks" "-fobjc-runtime=macosx-fragile" "-fencode-extended-block-signature"
"-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions"
"-fmax-type-align=16" "-fdiagnostics-show-option"
// TEST0: rewrite-legacy-objc.m"
// RUN: %clang -no-canonical-prefixes -target i386-apple-macosx10.9.0
-rewrite-legacy-objc %s -o - -### 2>&1 | \
// RUN: FileCheck -check-prefix=TEST1 %s
// RUN: %clang -no-canonical-prefixes -target i386-apple-macosx10.6.0
-rewrite-legacy-objc %s -o - -### 2>&1 | \
// RUN: FileCheck -check-prefix=TEST2 %s
-// TEST1: "-fmessage-length" "0" "-stack-protector" "1" "-mstackrealign"
"-fblocks" "-fobjc-runtime=macosx-fragile" "-fobjc-subscripting-legacy-runtime"
"-fencode-extended-block-signature" "-fno-objc-infer-related-result-type"
"-fobjc-exceptions" "-fdiagnostics-show-option"
-// TEST2: "-fmessage-length" "0" "-stack-protector" "1" "-mstackrealign"
"-fblocks" "-fobjc-runtime=macosx-fragile" "-fencode-extended-block-signature"
"-fno-objc-infer-related-result-type" "-fobjc-exceptions"
"-fdiagnostics-show-option"
+// TEST1: "-fmessage-length" "0" "-stack-protector" "1" "-mstackrealign"
"-fblocks" "-fobjc-runtime=macosx-fragile" "-fobjc-subscripting-legacy-runtime"
"-fencode-extended-block-signature" "-fno-objc-infer-related-result-type"
"-fobjc-exceptions" "-fmax-type-align=16" "-fdiagnostics-show-option"
+// TEST2: "-fmessage-length" "0" "-stack-protector" "1" "-mstackrealign"
"-fblocks" "-fobjc-runtime=macosx-fragile" "-fencode-extended-block-signature"
"-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fmax-type-align=16"
"-fdiagnostics-show-option"
Index: test/Driver/rewrite-objc.m
===================================================================
--- test/Driver/rewrite-objc.m (revision 214520)
+++ test/Driver/rewrite-objc.m (working copy)
@@ -3,4 +3,4 @@
// TEST0: clang{{.*}}" "-cc1"
// TEST0: "-rewrite-objc"
// FIXME: CHECK-NOT is broken somehow, it doesn't work here. Check adjacency
instead.
-// TEST0: "-fmessage-length" "0" "-stack-protector" "1" "-mstackrealign"
"-fblocks" "-fobjc-runtime=macosx" "-fencode-extended-block-signature"
"-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions"
"-fdiagnostics-show-option"
+// TEST0: "-fmessage-length" "0" "-stack-protector" "1" "-mstackrealign"
"-fblocks" "-fobjc-runtime=macosx" "-fencode-extended-block-signature"
"-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions"
"-fmax-type-align=16" "-fdiagnostics-show-option"
- Fariborz On Jul 28, 2014, at 6:58 PM, John McCall <[email protected]> wrote:
|
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
