forked from OSchip/llvm-project
[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
This commit is contained in:
parent
418de7d5d8
commit
f976ba6139
|
@ -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<
|
||||
|
|
|
@ -12350,6 +12350,8 @@ private:
|
|||
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);
|
||||
|
|
|
@ -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) ---------------===//
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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}}
|
||||
}
|
||||
|
|
@ -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}}
|
||||
}
|
Loading…
Reference in New Issue