[clang] f976ba6 - [PowerPC] Add Sema checks for MMA types
Baptiste Saleil via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 4 15:02:06 PST 2020
Author: Baptiste Saleil
Date: 2020-11-04T17:01:47-06:00
New Revision: f976ba61395811732b4605b6fb9b6ba5cd489372
URL: https://github.com/llvm/llvm-project/commit/f976ba61395811732b4605b6fb9b6ba5cd489372
DIFF: https://github.com/llvm/llvm-project/commit/f976ba61395811732b4605b6fb9b6ba5cd489372.diff
LOG: [PowerPC] Add Sema checks for MMA types
The use of the new types introduced for PowerPC MMA instructions needs to be restricted.
We add a PowerPC function checking that the given type is valid in a context in which we don't allow MMA types.
This function is called from various places in Sema where we want to prevent the use of these types.
Differential Revision: https://reviews.llvm.org/D82035
Added:
clang/test/Sema/ppc-mma-types.c
clang/test/SemaCXX/ppc-mma-types.cpp
Modified:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Sema/Sema.h
clang/lib/Sema/SemaChecking.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaExprCXX.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 83d968d3ae95..b9b76e8a9fb3 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9503,6 +9503,8 @@ def err_mips_builtin_requires_msa : Error<
"this builtin requires 'msa' ASE, please use -mmsa">;
def err_ppc_builtin_only_on_pwr7 : Error<
"this builtin is only valid on POWER7 or later CPUs">;
+def err_ppc_invalid_use_mma_type : Error<
+ "invalid use of PPC MMA type">;
def err_x86_builtin_invalid_rounding : Error<
"invalid rounding argument">;
def err_x86_builtin_invalid_scale : Error<
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index c42bc740ffa9..83d2a3122110 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -12350,6 +12350,8 @@ class Sema final {
bool SemaBuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall);
bool SemaBuiltinPPCMMACall(CallExpr *TheCall, const char *TypeDesc);
+ bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc);
+
// Matrix builtin handling.
ExprResult SemaBuiltinMatrixTranspose(CallExpr *TheCall,
ExprResult CallResult);
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 004028810d6e..eacf00c93015 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3307,6 +3307,23 @@ bool Sema::CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
return SemaBuiltinConstantArgRange(TheCall, i, l, u);
}
+// Check if the given type is a non-pointer PPC MMA type. This function is used
+// in Sema to prevent invalid uses of restricted PPC MMA types.
+bool Sema::CheckPPCMMAType(QualType Type, SourceLocation TypeLoc) {
+ if (Type->isPointerType() || Type->isArrayType())
+ return false;
+
+ QualType CoreType = Type.getCanonicalType().getUnqualifiedType();
+#define PPC_MMA_VECTOR_TYPE(Name, Id, Size) || CoreType == Context.Id##Ty
+ if (false
+#include "clang/Basic/PPCTypes.def"
+ ) {
+ Diag(TypeLoc, diag::err_ppc_invalid_use_mma_type);
+ return true;
+ }
+ return false;
+}
+
bool Sema::CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID,
CallExpr *TheCall) {
// position of memory order and scope arguments in the builtin
@@ -10315,6 +10332,11 @@ Sema::CheckReturnValExpr(Expr *RetValExp, QualType lhsType,
<< FD << getLangOpts().CPlusPlus11;
}
}
+
+ // PPC MMA non-pointer types are not allowed as return type. Checking the type
+ // here prevent the user from using a PPC MMA type as trailing return type.
+ if (Context.getTargetInfo().getTriple().isPPC64())
+ CheckPPCMMAType(RetValExp->getType(), ReturnLoc);
}
//===--- CHECK: Floating-Point comparisons (-Wfloat-equal) ---------------===//
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 6af2c188ba50..1afb4dcc7ff7 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -8037,6 +8037,14 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
NewVD->setInvalidDecl();
return;
}
+
+ // PPC MMA non-pointer types are not allowed as non-local variable types.
+ if (Context.getTargetInfo().getTriple().isPPC64() &&
+ !NewVD->isLocalVarDecl() &&
+ CheckPPCMMAType(T, NewVD->getLocation())) {
+ NewVD->setInvalidDecl();
+ return;
+ }
}
/// Perform semantic checking on a newly-created variable
@@ -10681,6 +10689,12 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
MergeTypeWithPrevious, Previous))
return Redeclaration;
+ // PPC MMA non-pointer types are not allowed as function return types.
+ if (Context.getTargetInfo().getTriple().isPPC64() &&
+ CheckPPCMMAType(NewFD->getReturnType(), NewFD->getLocation())) {
+ NewFD->setInvalidDecl();
+ }
+
// C++11 [dcl.constexpr]p8:
// A constexpr specifier for a non-static member function that is not
// a constructor declares that member function to be const.
@@ -13707,6 +13721,12 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc,
New->setInvalidDecl();
}
+ // PPC MMA non-pointer types are not allowed as function argument types.
+ if (Context.getTargetInfo().getTriple().isPPC64() &&
+ CheckPPCMMAType(New->getOriginalType(), New->getLocation())) {
+ New->setInvalidDecl();
+ }
+
return New;
}
@@ -16756,6 +16776,11 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
if (T.isObjCGCWeak())
Diag(Loc, diag::warn_attribute_weak_on_field);
+ // PPC MMA non-pointer types are not allowed as field types.
+ if (Context.getTargetInfo().getTriple().isPPC64() &&
+ CheckPPCMMAType(T, NewFD->getLocation()))
+ NewFD->setInvalidDecl();
+
NewFD->setAccess(AS);
return NewFD;
}
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 80b1e90faa0e..e36d9adfbaba 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -884,6 +884,10 @@ ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex,
Ex = Res.get();
}
+ // PPC MMA non-pointer types are not allowed as throw expr types.
+ if (Ex && Context.getTargetInfo().getTriple().isPPC64())
+ CheckPPCMMAType(Ex->getType(), Ex->getBeginLoc());
+
return new (Context)
CXXThrowExpr(Ex, Context.VoidTy, OpLoc, IsThrownVarInScope);
}
diff --git a/clang/test/Sema/ppc-mma-types.c b/clang/test/Sema/ppc-mma-types.c
new file mode 100644
index 000000000000..96644a4d9bbd
--- /dev/null
+++ b/clang/test/Sema/ppc-mma-types.c
@@ -0,0 +1,321 @@
+// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -fsyntax-only \
+// RUN: -target-cpu future %s -verify
+
+// The use of PPC MMA types is strongly restricted. Non-pointer MMA variables
+// can only be declared in functions and a limited number of operations are
+// supported on these types. This test case checks that invalid uses of MMA
+// types are correctly prevented.
+
+// vector quad
+
+// typedef
+typedef __vector_quad vq_t;
+void testVQTypedef(int *inp, int *outp) {
+ vq_t *vqin = (vq_t *)inp;
+ vq_t *vqout = (vq_t *)outp;
+ *vqout = *vqin;
+}
+
+// function argument
+void testVQArg1(__vector_quad vq, int *ptr) { // expected-error {{invalid use of PPC MMA type}}
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ *vqp = vq;
+}
+
+void testVQArg2(const __vector_quad vq, int *ptr) { // expected-error {{invalid use of PPC MMA type}}
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ *vqp = vq;
+}
+
+void testVQArg3(__vector_quad *vq, int *ptr) {
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ *vqp = *vq;
+}
+
+void testVQArg4(const __vector_quad *const vq, int *ptr) {
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ *vqp = *vq;
+}
+
+void testVQArg5(__vector_quad vqa[], int *ptr) {
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ *vqp = vqa[0];
+}
+
+void testVQArg6(const vq_t vq, int *ptr) { // expected-error {{invalid use of PPC MMA type}}
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ *vqp = vq;
+}
+
+void testVQArg7(const vq_t *vq, int *ptr) {
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ *vqp = *vq;
+}
+
+// function return
+__vector_quad testVQRet1(int *ptr) { // expected-error {{invalid use of PPC MMA type}}
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ return *vqp; // expected-error {{invalid use of PPC MMA type}}
+}
+
+__vector_quad *testVQRet2(int *ptr) {
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ return vqp + 2;
+}
+
+const __vector_quad *testVQRet3(int *ptr) {
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ return vqp + 2;
+}
+
+const vq_t testVQRet4(int *ptr) { // expected-error {{invalid use of PPC MMA type}}
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ return *vqp; // expected-error {{invalid use of PPC MMA type}}
+}
+
+const vq_t *testVQRet5(int *ptr) {
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ return vqp + 2;
+}
+
+// global
+__vector_quad globalvq; // expected-error {{invalid use of PPC MMA type}}
+const __vector_quad globalvq2; // expected-error {{invalid use of PPC MMA type}}
+__vector_quad *globalvqp;
+const __vector_quad *const globalvqp2;
+vq_t globalvq_t; // expected-error {{invalid use of PPC MMA type}}
+
+// local
+void testVQLocal(int *ptr, vector unsigned char vc) {
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ __vector_quad vq1 = *vqp;
+ __vector_quad vq2;
+ __builtin_mma_xxsetaccz(&vq2);
+ __vector_quad vq3;
+ __builtin_mma_xvi4ger8(&vq3, vc, vc);
+ *vqp = vq3;
+}
+
+// struct field
+struct TestVQStruct {
+ int a;
+ float b;
+ __vector_quad c; // expected-error {{invalid use of PPC MMA type}}
+ __vector_quad *vq;
+};
+
+// sizeof / alignof
+int testVQSizeofAlignof(int *ptr) {
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ __vector_quad vq = *vqp;
+ unsigned sizet = sizeof(__vector_quad);
+ unsigned alignt = __alignof__(__vector_quad);
+ unsigned sizev = sizeof(vq);
+ unsigned alignv = __alignof__(vq);
+ return sizet + alignt + sizev + alignv;
+}
+
+// operators
+int testVQOperators1(int *ptr) {
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ __vector_quad vq1 = *(vqp + 0);
+ __vector_quad vq2 = *(vqp + 1);
+ __vector_quad vq3 = *(vqp + 2);
+ if (vq1) // expected-error {{statement requires expression of scalar type ('__vector_quad' invalid)}}
+ *(vqp + 10) = vq1;
+ if (!vq2) // expected-error {{invalid argument type '__vector_quad' to unary expression}}
+ *(vqp + 11) = vq3;
+ int c1 = vq1 && vq2; // expected-error {{invalid operands to binary expression ('__vector_quad' and '__vector_quad')}}
+ int c2 = vq2 == vq3; // expected-error {{invalid operands to binary expression ('__vector_quad' and '__vector_quad')}}
+ int c3 = vq2 < vq1; // expected-error {{invalid operands to binary expression ('__vector_quad' and '__vector_quad')}}
+ return c1 || c2 || c3;
+}
+
+void testVQOperators2(int *ptr) {
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ __vector_quad vq1 = *(vqp + 0);
+ __vector_quad vq2 = *(vqp + 1);
+ __vector_quad vq3 = *(vqp + 2);
+ vq1 = -vq1; // expected-error {{invalid argument type '__vector_quad' to unary expression}}
+ vq2 = vq1 + vq3; // expected-error {{invalid operands to binary expression ('__vector_quad' and '__vector_quad')}}
+ vq2 = vq2 * vq3; // expected-error {{invalid operands to binary expression ('__vector_quad' and '__vector_quad')}}
+ vq3 = vq3 | vq3; // expected-error {{invalid operands to binary expression ('__vector_quad' and '__vector_quad')}}
+ vq3 = vq3 << 2; // expected-error {{invalid operands to binary expression ('__vector_quad' and 'int')}}
+ *(vqp + 10) = vq1;
+ *(vqp + 11) = vq2;
+ *(vqp + 12) = vq3;
+}
+
+vector unsigned char testVQOperators3(int *ptr) {
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ __vector_quad vq1 = *(vqp + 0);
+ __vector_quad vq2 = *(vqp + 1);
+ __vector_quad vq3 = *(vqp + 2);
+ vq1 ? *(vqp + 10) = vq2 : *(vqp + 11) = vq3; // expected-error {{used type '__vector_quad' where arithmetic or pointer type is required}}
+ vq2 = vq3;
+ return vq2[1]; // expected-error {{subscripted value is not an array, pointer, or vector}}
+}
+
+void testVQOperators4(int v, void *ptr) {
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ __vector_quad vq1 = (__vector_quad)v; // expected-error {{used type '__vector_quad' where arithmetic or pointer type is required}}
+ __vector_quad vq2 = (__vector_quad)vqp; // expected-error {{used type '__vector_quad' where arithmetic or pointer type is required}}
+}
+
+// vector pair
+
+// typedef
+typedef __vector_pair vp_t;
+void testVPTypedef(int *inp, int *outp) {
+ vp_t *vpin = (vp_t *)inp;
+ vp_t *vpout = (vp_t *)outp;
+ *vpout = *vpin;
+}
+
+// function argument
+void testVPArg1(__vector_pair vp, int *ptr) { // expected-error {{invalid use of PPC MMA type}}
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ *vpp = vp;
+}
+
+void testVPArg2(const __vector_pair vp, int *ptr) { // expected-error {{invalid use of PPC MMA type}}
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ *vpp = vp;
+}
+
+void testVPArg3(__vector_pair *vp, int *ptr) {
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ *vpp = *vp;
+}
+
+void testVPArg4(const __vector_pair *const vp, int *ptr) {
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ *vpp = *vp;
+}
+
+void testVPArg5(__vector_pair vpa[], int *ptr) {
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ *vpp = vpa[0];
+}
+
+void testVPArg6(const vp_t vp, int *ptr) { // expected-error {{invalid use of PPC MMA type}}
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ *vpp = vp;
+}
+
+void testVPArg7(const vp_t *vp, int *ptr) {
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ *vpp = *vp;
+}
+
+// function return
+__vector_pair testVPRet1(int *ptr) { // expected-error {{invalid use of PPC MMA type}}
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ return *vpp; // expected-error {{invalid use of PPC MMA type}}
+}
+
+__vector_pair *testVPRet2(int *ptr) {
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ return vpp + 2;
+}
+
+const __vector_pair *testVPRet3(int *ptr) {
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ return vpp + 2;
+}
+
+const vp_t testVPRet4(int *ptr) { // expected-error {{invalid use of PPC MMA type}}
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ return *vpp; // expected-error {{invalid use of PPC MMA type}}
+}
+
+const vp_t *testVPRet5(int *ptr) {
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ return vpp + 2;
+}
+
+// global
+__vector_pair globalvp; // expected-error {{invalid use of PPC MMA type}}
+const __vector_pair globalvp2; // expected-error {{invalid use of PPC MMA type}}
+__vector_pair *globalvpp;
+const __vector_pair *const globalvpp2;
+vp_t globalvp_t; // expected-error {{invalid use of PPC MMA type}}
+
+// local
+void testVPLocal(int *ptr, vector unsigned char vc) {
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ __vector_pair vp1 = *vpp;
+ __vector_pair vp2;
+ __builtin_mma_assemble_pair(&vp2, vc, vc);
+ __vector_pair vp3;
+ __vector_quad vq;
+ __builtin_mma_xvf64ger(&vq, vp3, vc);
+ *vpp = vp3;
+}
+
+// struct field
+struct TestVPStruct {
+ int a;
+ float b;
+ __vector_pair c; // expected-error {{invalid use of PPC MMA type}}
+ __vector_pair *vp;
+};
+
+// sizeof / alignof
+int testVPSizeofAlignof(int *ptr) {
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ __vector_pair vp = *vpp;
+ unsigned sizet = sizeof(__vector_pair);
+ unsigned alignt = __alignof__(__vector_pair);
+ unsigned sizev = sizeof(vp);
+ unsigned alignv = __alignof__(vp);
+ return sizet + alignt + sizev + alignv;
+}
+
+// operators
+int testVPOperators1(int *ptr) {
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ __vector_pair vp1 = *(vpp + 0);
+ __vector_pair vp2 = *(vpp + 1);
+ __vector_pair vp3 = *(vpp + 2);
+ if (vp1) // expected-error {{statement requires expression of scalar type ('__vector_pair' invalid)}}
+ *(vpp + 10) = vp1;
+ if (!vp2) // expected-error {{invalid argument type '__vector_pair' to unary expression}}
+ *(vpp + 11) = vp3;
+ int c1 = vp1 && vp2; // expected-error {{invalid operands to binary expression ('__vector_pair' and '__vector_pair')}}
+ int c2 = vp2 == vp3; // expected-error {{invalid operands to binary expression ('__vector_pair' and '__vector_pair')}}
+ int c3 = vp2 < vp1; // expected-error {{invalid operands to binary expression ('__vector_pair' and '__vector_pair')}}
+ return c1 || c2 || c3;
+}
+
+void testVPOperators2(int *ptr) {
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ __vector_pair vp1 = *(vpp + 0);
+ __vector_pair vp2 = *(vpp + 1);
+ __vector_pair vp3 = *(vpp + 2);
+ vp1 = -vp1; // expected-error {{invalid argument type '__vector_pair' to unary expression}}
+ vp2 = vp1 + vp3; // expected-error {{invalid operands to binary expression ('__vector_pair' and '__vector_pair')}}
+ vp2 = vp2 * vp3; // expected-error {{invalid operands to binary expression ('__vector_pair' and '__vector_pair')}}
+ vp3 = vp3 | vp3; // expected-error {{invalid operands to binary expression ('__vector_pair' and '__vector_pair')}}
+ vp3 = vp3 << 2; // expected-error {{invalid operands to binary expression ('__vector_pair' and 'int')}}
+ *(vpp + 10) = vp1;
+ *(vpp + 11) = vp2;
+ *(vpp + 12) = vp3;
+}
+
+vector unsigned char testVPOperators3(int *ptr) {
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ __vector_pair vp1 = *(vpp + 0);
+ __vector_pair vp2 = *(vpp + 1);
+ __vector_pair vp3 = *(vpp + 2);
+ vp1 ? *(vpp + 10) = vp2 : *(vpp + 11) = vp3; // expected-error {{used type '__vector_pair' where arithmetic or pointer type is required}}
+ vp2 = vp3;
+ return vp2[1]; // expected-error {{subscripted value is not an array, pointer, or vector}}
+}
+
+void testVPOperators4(int v, void *ptr) {
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ __vector_pair vp1 = (__vector_pair)v; // expected-error {{used type '__vector_pair' where arithmetic or pointer type is required}}
+ __vector_pair vp2 = (__vector_pair)vpp; // expected-error {{used type '__vector_pair' where arithmetic or pointer type is required}}
+}
+
diff --git a/clang/test/SemaCXX/ppc-mma-types.cpp b/clang/test/SemaCXX/ppc-mma-types.cpp
new file mode 100644
index 000000000000..86487586e9b2
--- /dev/null
+++ b/clang/test/SemaCXX/ppc-mma-types.cpp
@@ -0,0 +1,384 @@
+// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -fsyntax-only \
+// RUN: -fcxx-exceptions -target-cpu future %s -verify
+
+// vector quad
+
+// alias
+using vq_t = __vector_quad;
+void testVQAlias(int *inp, int *outp) {
+ vq_t *vqin = (vq_t *)inp;
+ vq_t *vqout = (vq_t *)outp;
+ *vqout = *vqin;
+}
+
+class TestClassVQ {
+ // method argument
+public:
+ void testVQArg1(__vector_quad vq, int *ptr) { // expected-error {{invalid use of PPC MMA type}}
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ *vqp = vq;
+ *vqp1 = vq;
+ }
+ void testVQArg2(const __vector_quad vq, int *ptr) { // expected-error {{invalid use of PPC MMA type}}
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ *vqp = vq;
+ *vqp2 = vq;
+ }
+ void testVQArg3(__vector_quad *vq, int *ptr) {
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ *vqp = *vq;
+ vqp1 = vqp;
+ }
+ void testVQArg4(const __vector_quad *const vq, int *ptr) {
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ *vqp = *vq;
+ vqp2 = vqp;
+ }
+ void testVQArg5(__vector_quad vqa[], int *ptr) {
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ *vqp = vqa[0];
+ *vqp1 = vqa[1];
+ }
+ void testVQArg6(const vq_t vq, int *ptr) { // expected-error {{invalid use of PPC MMA type}}
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ *vqp = vq;
+ *vqp2 = vq;
+ }
+ void testVQArg7(const vq_t *vq, int *ptr) {
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ *vqp = *vq;
+ vqp1 = vqp;
+ }
+
+ // method return
+ __vector_quad testVQRet1(int *ptr) { // expected-error {{invalid use of PPC MMA type}}
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ vq1 = *vqp;
+ return *vqp; // expected-error {{invalid use of PPC MMA type}}
+ }
+
+ __vector_quad *testVQRet2(int *ptr) {
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ vq2 = *vqp;
+ return vqp + 2;
+ }
+
+ const __vector_quad *testVQRet3(int *ptr) {
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ vqp1 = vqp;
+ return vqp + 2;
+ }
+
+ const vq_t testVQRet4(int *ptr) { // expected-error {{invalid use of PPC MMA type}}
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ vqp2 = vqp;
+ return *vqp; // expected-error {{invalid use of PPC MMA type}}
+ }
+
+ const vq_t *testVQRet5(int *ptr) {
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ vq1 = *vqp;
+ return vqp + 2;
+ }
+
+ // template argument
+ template <typename T = __vector_quad>
+ void testVQTemplate(T v, T *p) { // expected-note {{candidate template ignored: substitution failure [with T = __vector_quad]: invalid use of PPC MMA type}} \
+ expected-note {{candidate template ignored: substitution failure [with T = __vector_quad]: invalid use of PPC MMA type}}
+ *(p + 1) = v;
+ }
+
+ // class field
+public:
+ __vector_quad vq1; // expected-error {{invalid use of PPC MMA type}}
+ __vector_quad *vqp1;
+
+private:
+ vq_t vq2; // expected-error {{invalid use of PPC MMA type}}
+ vq_t *vqp2;
+};
+
+// template
+template <typename T>
+class ClassTemplateVQ1 {
+ T t; // expected-error {{invalid use of PPC MMA type}}
+};
+template <typename T>
+class ClassTemplateVQ2 {
+ T *t;
+};
+template <typename T>
+class ClassTemplateVQ3 {
+ int foo(T t) { return 10; }
+};
+template <typename T, typename... Ts>
+class ClassTemplateVQ4 {
+public:
+ T operator()(Ts...) const {} // expected-error {{invalid use of PPC MMA type}}
+};
+void testVQTemplate() {
+ ClassTemplateVQ1<__vector_quad> t1; // expected-note {{in instantiation of template class 'ClassTemplateVQ1<__vector_quad>' requested here}}
+ ClassTemplateVQ1<__vector_quad *> t2;
+ ClassTemplateVQ2<__vector_quad> t3;
+ ClassTemplateVQ2<__vector_quad *> t4;
+
+ ClassTemplateVQ3<int(int, int, int)> t5;
+ // The following case is not prevented but it ok, this function type cannot be
+ // instantiated because we prevent any function from returning an MMA type.
+ ClassTemplateVQ3<__vector_quad(int, int, int)> t6;
+ ClassTemplateVQ3<int(__vector_quad, int, int)> t7; // expected-error {{invalid use of PPC MMA type}}
+
+ ClassTemplateVQ4<int, int, int, __vector_quad> t8; // expected-note {{in instantiation of template class 'ClassTemplateVQ4<int, int, int, __vector_quad>' requested here}}
+ ClassTemplateVQ4<int, int, int, __vector_quad *> t9;
+
+ TestClassVQ tc;
+ __vector_quad vq;
+ __vector_quad *vqp = &vq;
+ tc.testVQTemplate(&vq, &vqp);
+ tc.testVQTemplate<vq_t *>(&vq, &vqp);
+ tc.testVQTemplate(vq, vqp); // expected-error {{no matching member function for call to 'testVQTemplate'}}
+ tc.testVQTemplate<vq_t>(vq, vqp); // expected-error {{no matching member function for call to 'testVQTemplate'}}
+}
+
+// trailing return type
+auto testVQTrailing1() {
+ __vector_quad vq;
+ return vq; // expected-error {{invalid use of PPC MMA type}}
+}
+auto testVQTrailing2() {
+ __vector_quad *vqp;
+ return vqp;
+}
+auto testVQTrailing3() -> vq_t { // expected-error {{invalid use of PPC MMA type}}
+ __vector_quad vq;
+ return vq; // expected-error {{invalid use of PPC MMA type}}
+}
+auto testVQTrailing4() -> vq_t * {
+ __vector_quad *vqp;
+ return vqp;
+}
+
+// new/delete
+void testVQNewDelete() {
+ __vector_quad *vqp1 = new __vector_quad;
+ __vector_quad *vqp2 = new __vector_quad[100];
+ delete vqp1;
+ delete[] vqp2;
+}
+
+// lambdas expressions
+void TestVQLambda() {
+ auto f1 = [](void *ptr) -> __vector_quad {
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ return *vqp; // expected-error {{invalid use of PPC MMA type}}
+ };
+ auto f2 = [](void *ptr) {
+ __vector_quad *vqp = (__vector_quad *)ptr;
+ return *vqp; // expected-error {{invalid use of PPC MMA type}}
+ };
+ auto f3 = [] { __vector_quad vq; __builtin_mma_xxsetaccz(&vq); return vq; }; // expected-error {{invalid use of PPC MMA type}}
+}
+
+// cast
+void TestVQCast() {
+ __vector_quad vq;
+ int *ip = reinterpret_cast<int *>(&vq);
+ __vector_quad *vq2 = reinterpret_cast<__vector_quad *>(ip);
+}
+
+// throw
+void TestVQThrow() {
+ __vector_quad vq;
+ throw vq; // expected-error {{invalid use of PPC MMA type}}
+}
+
+// vector pair
+
+// alias
+using vp_t = __vector_pair;
+void testVPAlias(int *inp, int *outp) {
+ vp_t *vpin = (vp_t *)inp;
+ vp_t *vpout = (vp_t *)outp;
+ *vpout = *vpin;
+}
+
+class TestClassVP {
+ // method argument
+public:
+ void testVPArg1(__vector_pair vp, int *ptr) { // expected-error {{invalid use of PPC MMA type}}
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ *vpp = vp;
+ *vpp1 = vp;
+ }
+ void testVPArg2(const __vector_pair vp, int *ptr) { // expected-error {{invalid use of PPC MMA type}}
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ *vpp = vp;
+ *vpp2 = vp;
+ }
+ void testVPArg3(__vector_pair *vp, int *ptr) {
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ *vpp = *vp;
+ vpp1 = vpp;
+ }
+ void testVPArg4(const __vector_pair *const vp, int *ptr) {
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ *vpp = *vp;
+ vpp2 = vpp;
+ }
+ void testVPArg5(__vector_pair vpa[], int *ptr) {
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ *vpp = vpa[0];
+ *vpp1 = vpa[1];
+ }
+ void testVPArg6(const vp_t vp, int *ptr) { // expected-error {{invalid use of PPC MMA type}}
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ *vpp = vp;
+ *vpp2 = vp;
+ }
+ void testVPArg7(const vp_t *vp, int *ptr) {
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ *vpp = *vp;
+ vpp1 = vpp;
+ }
+
+ // method return
+ __vector_pair testVPRet1(int *ptr) { // expected-error {{invalid use of PPC MMA type}}
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ vp1 = *vpp;
+ return *vpp; // expected-error {{invalid use of PPC MMA type}}
+ }
+
+ __vector_pair *testVPRet2(int *ptr) {
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ vp2 = *vpp;
+ return vpp + 2;
+ }
+
+ const __vector_pair *testVPRet3(int *ptr) {
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ vpp1 = vpp;
+ return vpp + 2;
+ }
+
+ const vp_t testVPRet4(int *ptr) { // expected-error {{invalid use of PPC MMA type}}
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ vpp2 = vpp;
+ return *vpp; // expected-error {{invalid use of PPC MMA type}}
+ }
+
+ const vp_t *testVPRet5(int *ptr) {
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ vp1 = *vpp;
+ return vpp + 2;
+ }
+
+ // template argument
+ template <typename T = __vector_pair>
+ void testVPTemplate(T v, T *p) { // expected-note {{candidate template ignored: substitution failure [with T = __vector_pair]: invalid use of PPC MMA type}} \
+ expected-note {{candidate template ignored: substitution failure [with T = __vector_pair]: invalid use of PPC MMA type}}
+ *(p + 1) = v;
+ }
+
+ // class field
+public:
+ __vector_pair vp1; // expected-error {{invalid use of PPC MMA type}}
+ __vector_pair *vpp1;
+
+private:
+ vp_t vp2; // expected-error {{invalid use of PPC MMA type}}
+ vp_t *vpp2;
+};
+
+// template
+template <typename T>
+class ClassTemplateVP1 {
+ T t; // expected-error {{invalid use of PPC MMA type}}
+};
+template <typename T>
+class ClassTemplateVP2 {
+ T *t;
+};
+template <typename T>
+class ClassTemplateVP3 {
+ int foo(T t) { return 10; }
+};
+template <typename T, typename... Ts>
+class ClassTemplateVP4 {
+public:
+ T operator()(Ts...) const {} // expected-error {{invalid use of PPC MMA type}}
+};
+void testVPTemplate() {
+ ClassTemplateVP1<__vector_pair> t1; // expected-note {{in instantiation of template class 'ClassTemplateVP1<__vector_pair>' requested here}}
+ ClassTemplateVP1<__vector_pair *> t2;
+ ClassTemplateVP2<__vector_pair> t3;
+ ClassTemplateVP2<__vector_pair *> t4;
+
+ ClassTemplateVP3<int(int, int, int)> t5;
+ // The following case is not prevented but it ok, this function type cannot be
+ // instantiated because we prevent any function from returning an MMA type.
+ ClassTemplateVP3<__vector_pair(int, int, int)> t6;
+ ClassTemplateVP3<int(__vector_pair, int, int)> t7; // expected-error {{invalid use of PPC MMA type}}
+
+ ClassTemplateVP4<int, int, int, __vector_pair> t8; // expected-note {{in instantiation of template class 'ClassTemplateVP4<int, int, int, __vector_pair>' requested here}}
+ ClassTemplateVP4<int, int, int, __vector_pair *> t9;
+
+ TestClassVP tc;
+ __vector_pair vp;
+ __vector_pair *vpp = &vp;
+ tc.testVPTemplate(&vp, &vpp);
+ tc.testVPTemplate<vp_t *>(&vp, &vpp);
+ tc.testVPTemplate(vp, vpp); // expected-error {{no matching member function for call to 'testVPTemplate'}}
+ tc.testVPTemplate<vp_t>(vp, vpp); // expected-error {{no matching member function for call to 'testVPTemplate'}}
+}
+
+// trailing return type
+auto testVPTrailing1() {
+ __vector_pair vp;
+ return vp; // expected-error {{invalid use of PPC MMA type}}
+}
+auto testVPTrailing2() {
+ __vector_pair *vpp;
+ return vpp;
+}
+auto testVPTrailing3() -> vp_t { // expected-error {{invalid use of PPC MMA type}}
+ __vector_pair vp;
+ return vp; // expected-error {{invalid use of PPC MMA type}}
+}
+auto testVPTrailing4() -> vp_t * {
+ __vector_pair *vpp;
+ return vpp;
+}
+
+// new/delete
+void testVPNewDelete() {
+ __vector_pair *vpp1 = new __vector_pair;
+ __vector_pair *vpp2 = new __vector_pair[100];
+ delete vpp1;
+ delete[] vpp2;
+}
+
+// lambdas expressions
+void TestVPLambda() {
+ auto f1 = [](void *ptr) -> __vector_pair {
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ return *vpp; // expected-error {{invalid use of PPC MMA type}}
+ };
+ auto f2 = [](void *ptr) {
+ __vector_pair *vpp = (__vector_pair *)ptr;
+ return *vpp; // expected-error {{invalid use of PPC MMA type}}
+ };
+ auto f3 = [](vector unsigned char vc) { __vector_pair vp; __builtin_mma_assemble_pair(&vp, vc, vc); return vp; }; // expected-error {{invalid use of PPC MMA type}}
+}
+
+// cast
+void TestVPCast() {
+ __vector_pair vp;
+ int *ip = reinterpret_cast<int *>(&vp);
+ __vector_pair *vp2 = reinterpret_cast<__vector_pair *>(ip);
+}
+
+// throw
+void TestVPThrow() {
+ __vector_pair vp;
+ throw vp; // expected-error {{invalid use of PPC MMA type}}
+}
More information about the cfe-commits
mailing list