[PATCH] Support base vector types of __attribute__((mode))
Aaron Ballman
aaron.ballman at gmail.com
Wed May 27 08:20:17 PDT 2015
On Wed, May 27, 2015 at 8:03 AM, Alexey Frolov <alexfrolov1878 at yandex.ru> wrote:
> Hi aaron.ballman, rsmith,
>
> Base type of __attribute__((mode)) can actually be a vector type.
I am unfamiliar with __attribute__((mode)); is there documentation
that supports this assertion, or popular code in the wild that is
relying on it? GCC's docs are very spartan on the topic, and there was
an (unanswered) question in the PR regarding why we would want to
support this.
> The patch is to distinguish between base type and base element type.
>
> This fixes http://llvm.org/PR17453.
Some comments below regarding the patch.
>
> REPOSITORY
> rL LLVM
>
> http://reviews.llvm.org/D10058
>
> Files:
> include/clang/Basic/DiagnosticSemaKinds.td
> lib/Sema/SemaDeclAttr.cpp
> test/CodeGen/attr-mode-vector-types.c
> test/Sema/attr-mode-vector-types.c
>
> EMAIL PREFERENCES
> http://reviews.llvm.org/settings/panel/emailpreferences/
> Index: test/Sema/attr-mode-vector-types.c
> ===================================================================
> --- test/Sema/attr-mode-vector-types.c
> +++ test/Sema/attr-mode-vector-types.c
> @@ -0,0 +1,26 @@
> +// RUN: %clang_cc1 -fsyntax-only -verify %s
> +
> +// Correct cases.
> +typedef int __attribute__((mode(byte))) __attribute__((vector_size(256))) vec_t1;
> +typedef int __attribute__((mode(QI))) __attribute__((vector_size(256))) vec_t2;
> +typedef int __attribute__((mode(SI))) __attribute__((vector_size(256))) vec_t3;
> +typedef int __attribute__((mode(DI))) __attribute__((vector_size(256)))vec_t4;
> +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;
> +
> +// Incorrect cases.
> +typedef float __attribute__((mode(QC))) __attribute__((vector_size(256))) vec_t8;
> +// expected-error at -1{{unsupported machine mode 'QC'}}
> +// expected-error at -2{{type of machine mode does not match type of base type}}
> +typedef _Complex float __attribute__((mode(HC))) __attribute__((vector_size(256))) vec_t9;
> +// expected-error at -1{{unsupported machine mode 'HC'}}
> +// expected-error at -2{{invalid vector element type '_Complex float'}}
> +typedef int __attribute__((mode(SC))) __attribute__((vector_size(256))) vec_t10;
> +// expected-error at -1{{type of machine mode does not match type of base type}}
> +// expected-error at -2{{type of machine mode does not support base vector types}}
> +typedef float __attribute__((mode(DC))) __attribute__((vector_size(256))) vec_t11;
> +// expected-error at -1{{type of machine mode does not match type of base type}}
> +// expected-error at -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 at -1{{invalid vector element type '_Complex float'}}
> Index: test/CodeGen/attr-mode-vector-types.c
> ===================================================================
> --- test/CodeGen/attr-mode-vector-types.c
> +++ test/CodeGen/attr-mode-vector-types.c
> @@ -0,0 +1,41 @@
> +// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -emit-llvm -o - | FileCheck %s
> +
> +typedef int __attribute__((mode(byte))) __attribute__((vector_size(4))) vec_t1;
> +typedef int __attribute__((mode(QI))) __attribute__((vector_size(8))) vec_t2;
> +typedef int __attribute__((mode(SI))) __attribute__((vector_size(16))) vec_t3;
> +typedef int __attribute__((mode(DI))) __attribute__((vector_size(64)))vec_t4;
> +typedef float __attribute__((mode(SF))) __attribute__((vector_size(128))) vec_t5;
> +typedef float __attribute__((mode(DF))) __attribute__((vector_size(256))) vec_t6;
> +
> +void check() {
> + // CHECK: alloca <4 x i8>
> + vec_t1 v1;
> + // CHECK: alloca <8 x i8>
> + vec_t2 v2;
> + // CHECK: alloca <4 x i32>
> + vec_t3 v3;
> + // CHECK: alloca <8 x i64>
> + vec_t4 v4;
> + // CHECK: alloca <32 x float>
> + vec_t5 v5;
> + // CHECK: alloca <32 x double>
> + vec_t6 v6;
> +}
> +
> +// CHECK: ret i32 4
> +int check_size1() { return sizeof(vec_t1); }
> +
> +// CHECK: ret i32 8
> +int check_size2() { return sizeof(vec_t2); }
> +
> +// CHECK: ret i32 16
> +int check_size3() { return sizeof(vec_t3); }
> +
> +// CHECK: ret i32 64
> +int check_size4() { return sizeof(vec_t4); }
> +
> +// CHECK: ret i32 128
> +int check_size5() { return sizeof(vec_t5); }
> +
> +// CHECK: ret i32 256
> +int check_size6() { return sizeof(vec_t6); }
> Index: include/clang/Basic/DiagnosticSemaKinds.td
> ===================================================================
> --- include/clang/Basic/DiagnosticSemaKinds.td
> +++ include/clang/Basic/DiagnosticSemaKinds.td
> @@ -2685,6 +2685,8 @@
> "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 err_complex_mode_vector_type : Error<
> + "type of machine mode does not support base vector types">;
> def err_attr_wrong_decl : Error<
> "%0 attribute invalid on this declaration, requires typedef or value">;
> def warn_attribute_nonnull_no_pointers : Warning<
> Index: lib/Sema/SemaDeclAttr.cpp
> ===================================================================
> --- lib/Sema/SemaDeclAttr.cpp
> +++ lib/Sema/SemaDeclAttr.cpp
> @@ -3132,16 +3132,22 @@
> return;
> }
>
> - if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
> + // Base type can be a vector type (see PR17453).
> + // Distinguish between base type and base element type.
> + QualType OldElemTy = OldTy;
> + if (const VectorType *VT = OldTy->getAs<VectorType>())
> + OldElemTy = VT->getElementType();
> +
> + if (!OldElemTy->getAs<BuiltinType>() && !OldElemTy->isComplexType())
> S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
> else if (IntegerMode) {
> - if (!OldTy->isIntegralOrEnumerationType())
> + if (!OldElemTy->isIntegralOrEnumerationType())
> S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
> } else if (ComplexMode) {
> - if (!OldTy->isComplexType())
> + if (!OldElemTy->isComplexType())
> S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
> } else {
> - if (!OldTy->isFloatingType())
> + if (!OldElemTy->isFloatingType())
> S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
> }
>
> @@ -3154,21 +3160,40 @@
> return;
> }
>
> - QualType NewTy;
> + QualType NewElemTy;
>
> if (IntegerMode)
> - NewTy = S.Context.getIntTypeForBitwidth(DestWidth,
> - OldTy->isSignedIntegerType());
> + NewElemTy = S.Context.getIntTypeForBitwidth(
> + DestWidth, OldElemTy->isSignedIntegerType());
> else
> - NewTy = S.Context.getRealTypeForBitwidth(DestWidth);
> + NewElemTy = S.Context.getRealTypeForBitwidth(DestWidth);
>
> - if (NewTy.isNull()) {
> + if (NewElemTy.isNull()) {
> S.Diag(Attr.getLoc(), diag::err_machine_mode) << 1 /*Unsupported*/ << Name;
> return;
> }
>
> if (ComplexMode) {
> - NewTy = S.Context.getComplexType(NewTy);
> + NewElemTy = S.Context.getComplexType(NewElemTy);
> + }
> +
> + QualType NewTy = NewElemTy;
> + 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) << Name;
The diagnostic you added does not accept any arguments.
> + return;
> + }
> + unsigned NumElements = S.Context.getTypeSize(OldElemTy) *
> + OldVT->getNumElements() /
> + S.Context.getTypeSize(NewElemTy);
> + NewTy =
> + S.Context.getVectorType(NewElemTy, NumElements, OldVT->getVectorKind());
> + }
> +
> + if (NewTy.isNull()) {
> + S.Diag(Attr.getLoc(), diag::err_mode_wrong_type) << Name;
This diagnostic also does not accept any arguments.
> + return;
> }
>
> // Install the new type.
>
~Aaron
More information about the cfe-commits
mailing list