DmitryPolukhin created this revision. DmitryPolukhin added a reviewer: aaron.ballman. DmitryPolukhin added a subscriber: cfe-commits.
Add support for vector mode attributes like "__attribute__((mode(V4SF)))". Also add warning about deprecated vector modes like GCC does. http://reviews.llvm.org/D14744 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDeclAttr.cpp test/Sema/attr-mode-vector-types.c
Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -3215,38 +3215,31 @@ return true; } -/// handleModeAttr - This attribute modifies the width of a decl with primitive -/// type. -/// -/// Despite what would be logical, the mode attribute is a decl attribute, not a -/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be -/// HImode, not an intermediate pointer. -static void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) { - // This attribute isn't documented, but glibc uses it. It changes - // the width of an int or unsigned int to the specified size. - if (!Attr.isArgIdent(0)) { - S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << Attr.getName() - << AANT_ArgumentIdentifier; - return; - } - - IdentifierInfo *Name = Attr.getArgAsIdent(0)->Ident; - StringRef Str = Name->getName(); - - normalizeName(Str); - - unsigned DestWidth = 0; - bool IntegerMode = true; - bool ComplexMode = false; +/// parseModeAttr - Parses attribute mode string and returns parsed type +/// attribute. +static void parseModeAttr(Sema &S, StringRef Str, unsigned &DestWidth, + bool &IntegerMode, bool &ComplexMode) { switch (Str.size()) { case 2: switch (Str[0]) { - case 'Q': DestWidth = 8; break; - case 'H': DestWidth = 16; break; - case 'S': DestWidth = 32; break; - case 'D': DestWidth = 64; break; - case 'X': DestWidth = 96; break; - case 'T': DestWidth = 128; break; + case 'Q': + DestWidth = 8; + break; + case 'H': + DestWidth = 16; + break; + case 'S': + DestWidth = 32; + break; + case 'D': + DestWidth = 64; + break; + case 'X': + DestWidth = 96; + break; + case 'T': + DestWidth = 128; + break; } if (Str[1] == 'F') { IntegerMode = false; @@ -3274,6 +3267,50 @@ DestWidth = S.Context.getTargetInfo().getUnwindWordWidth(); break; } +} + +/// handleModeAttr - This attribute modifies the width of a decl with primitive +/// type. +/// +/// Despite what would be logical, the mode attribute is a decl attribute, not a +/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be +/// HImode, not an intermediate pointer. +static void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) { + // This attribute isn't documented, but glibc uses it. It changes + // the width of an int or unsigned int to the specified size. + if (!Attr.isArgIdent(0)) { + S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << Attr.getName() + << AANT_ArgumentIdentifier; + return; + } + + IdentifierInfo *Name = Attr.getArgAsIdent(0)->Ident; + StringRef Str = Name->getName(); + + normalizeName(Str); + + unsigned DestWidth = 0; + bool IntegerMode = true; + bool ComplexMode = false; + llvm::APInt VectorSize(64, 0); + if (Str.size() >= 4 && Str[0] == 'V') { + // Minimal length of vector mode is 4: 'V' + NUMBER(>=1) + TYPE(>=2). + int VectorStringLength = 0; + while (isdigit(Str[VectorStringLength + 1])) + ++VectorStringLength; + if (VectorStringLength && + !Str.substr(1, VectorStringLength).getAsInteger(10, VectorSize) && + VectorSize.isPowerOf2()) { + parseModeAttr(S, Str.substr(VectorStringLength + 1), DestWidth, + IntegerMode, ComplexMode); + S.Diag(Attr.getLoc(), diag::warn_vector_mode_deprecated); + } else { + VectorSize = 0; + } + } + + if (!VectorSize) + parseModeAttr(S, Str, DestWidth, IntegerMode, ComplexMode); QualType OldTy; if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) @@ -3332,7 +3369,10 @@ } QualType NewTy = NewElemTy; - if (const VectorType *OldVT = OldTy->getAs<VectorType>()) { + if (VectorSize.getBoolValue()) { + NewTy = S.Context.getVectorType(NewTy, VectorSize.getZExtValue(), + VectorType::GenericVector); + } else if (const VectorType *OldVT = OldTy->getAs<VectorType>()) { // Complex machine mode does not support base vector types. if (ComplexMode) { S.Diag(Attr.getLoc(), diag::err_complex_mode_vector_type); Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -2761,6 +2761,10 @@ "mode attribute only supported for integer and floating-point types">; def err_mode_wrong_type : Error< "type of machine mode does not match type of base type">; +def warn_vector_mode_deprecated : Warning< + "specifying vector types with __attribute__ ((mode)) is deprecated, " + "use __attribute__ ((vector_size)) instead">, + InGroup<IgnoredAttributes>; def err_complex_mode_vector_type : Error< "type of machine mode does not support base vector types">; def err_attr_wrong_decl : Error< Index: test/Sema/attr-mode-vector-types.c =================================================================== --- test/Sema/attr-mode-vector-types.c +++ test/Sema/attr-mode-vector-types.c @@ -9,6 +9,14 @@ typedef float __attribute__((mode(DF))) __attribute__((vector_size(256))) vec_t6; typedef float __attribute__((mode(XF))) __attribute__((vector_size(256))) vec_t7; +typedef int v8qi __attribute__ ((mode(QI))) __attribute__ ((vector_size(8))); +typedef int v8qi __attribute__ ((mode(V8QI))); +// expected-warning@-1{{specifying vector types with __attribute__ ((mode)) is deprecated, use __attribute__ ((vector_size)) instead}} + +typedef float v4sf __attribute__((mode(V4SF))); +// expected-warning@-1{{specifying vector types with __attribute__ ((mode)) is deprecated, use __attribute__ ((vector_size)) instead}} +typedef float v4sf __attribute__((mode(SF))) __attribute__ ((vector_size(16))); + // Incorrect cases. typedef float __attribute__((mode(QC))) __attribute__((vector_size(256))) vec_t8; // expected-error@-1{{unsupported machine mode 'QC'}} @@ -24,3 +32,5 @@ // expected-error@-2{{type of machine mode does not support base vector types}} typedef _Complex float __attribute__((mode(XC))) __attribute__((vector_size(256))) vec_t12; // expected-error@-1{{invalid vector element type '_Complex float'}} +typedef int __attribute__((mode(V3QI))) v3qi; +// expected-error@-1{{unknown machine mode 'V3QI'}}
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits