forked from OSchip/llvm-project
PR10235: support for vector mode attributes + warning, by Dmitry Polukhin.
Add support for vector mode attributes like "attribute((mode(V4SF)))". Also add warning about deprecated vector modes like GCC does. Differential Revision: http://reviews.llvm.org/D14744 llvm-svn: 253551
This commit is contained in:
parent
0ecdbe7d6b
commit
f278eb10b7
|
@ -83,6 +83,7 @@ def AbstractFinalClass : DiagGroup<"abstract-final-class">;
|
|||
def CXX11CompatDeprecatedWritableStr :
|
||||
DiagGroup<"c++11-compat-deprecated-writable-strings">;
|
||||
|
||||
def DeprecatedAttributes : DiagGroup<"deprecated-attributes">;
|
||||
def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">;
|
||||
def UnavailableDeclarations : DiagGroup<"unavailable-declarations">;
|
||||
def PartialAvailability : DiagGroup<"partial-availability">;
|
||||
|
@ -92,7 +93,8 @@ def DeprecatedRegister : DiagGroup<"deprecated-register">;
|
|||
def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings",
|
||||
[CXX11CompatDeprecatedWritableStr]>;
|
||||
// FIXME: Why is DeprecatedImplementations not in this group?
|
||||
def Deprecated : DiagGroup<"deprecated", [DeprecatedDeclarations,
|
||||
def Deprecated : DiagGroup<"deprecated", [DeprecatedAttributes,
|
||||
DeprecatedDeclarations,
|
||||
DeprecatedIncrementBool,
|
||||
DeprecatedRegister,
|
||||
DeprecatedWritableStr]>,
|
||||
|
|
|
@ -2823,6 +2823,10 @@ def err_mode_not_primitive : Error<
|
|||
"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 the 'mode' attribute is deprecated; "
|
||||
"use the 'vector_size' attribute instead">,
|
||||
InGroup<DeprecatedAttributes>;
|
||||
def err_complex_mode_vector_type : Error<
|
||||
"type of machine mode does not support base vector types">;
|
||||
def err_attr_wrong_decl : Error<
|
||||
|
|
|
@ -3234,38 +3234,31 @@ bool Sema::checkMSInheritanceAttrOnDefinition(
|
|||
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;
|
||||
/// parseModeAttrArg - Parses attribute mode string and returns parsed type
|
||||
/// attribute.
|
||||
static void parseModeAttrArg(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;
|
||||
|
@ -3293,6 +3286,52 @@ static void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
|
|||
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).
|
||||
size_t StrSize = Str.size();
|
||||
size_t VectorStringLength = 0;
|
||||
while ((VectorStringLength + 1) < StrSize &&
|
||||
isdigit(Str[VectorStringLength + 1]))
|
||||
++VectorStringLength;
|
||||
if (VectorStringLength &&
|
||||
!Str.substr(1, VectorStringLength).getAsInteger(10, VectorSize) &&
|
||||
VectorSize.isPowerOf2()) {
|
||||
parseModeAttrArg(S, Str.substr(VectorStringLength + 1), DestWidth,
|
||||
IntegerMode, ComplexMode);
|
||||
S.Diag(Attr.getLoc(), diag::warn_vector_mode_deprecated);
|
||||
} else {
|
||||
VectorSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!VectorSize)
|
||||
parseModeAttrArg(S, Str, DestWidth, IntegerMode, ComplexMode);
|
||||
|
||||
QualType OldTy;
|
||||
if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
|
||||
|
@ -3351,7 +3390,10 @@ static void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
|
|||
}
|
||||
|
||||
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);
|
||||
|
|
|
@ -9,6 +9,14 @@ typedef float __attribute__((mode(SF))) __attribute__((vector_size(256))) vec_t5
|
|||
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 the 'mode' attribute is deprecated; use the 'vector_size' attribute instead}}
|
||||
|
||||
typedef float v4sf __attribute__((mode(V4SF)));
|
||||
// expected-warning@-1{{specifying vector types with the 'mode' attribute is deprecated; use the 'vector_size' attribute 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 @@ typedef float __attribute__((mode(DC))) __attribute__((vector_size(256))) vec_t1
|
|||
// 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'}}
|
||||
|
|
Loading…
Reference in New Issue