diff options
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/CheckExprLifetime.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 30 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaHLSL.cpp | 39 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 87 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaObjCProperty.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 11 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaRISCV.cpp | 74 |
7 files changed, 194 insertions, 50 deletions
diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp index e797400..f9665b5 100644 --- a/clang/lib/Sema/CheckExprLifetime.cpp +++ b/clang/lib/Sema/CheckExprLifetime.cpp @@ -155,6 +155,7 @@ getEntityLifetime(const InitializedEntity *Entity, case InitializedEntity::EK_LambdaToBlockConversionBlockElement: case InitializedEntity::EK_LambdaCapture: case InitializedEntity::EK_VectorElement: + case InitializedEntity::EK_MatrixElement: case InitializedEntity::EK_ComplexElement: return {nullptr, LK_FullExpression}; diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index f99c01e..f451787 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -12373,14 +12373,9 @@ static void DiagnoseMixedUnicodeImplicitConversion(Sema &S, const Type *Source, } } -enum CFIUncheckedCalleeChange { - None, - Adding, - Discarding, -}; - -static CFIUncheckedCalleeChange AdjustingCFIUncheckedCallee(QualType From, - QualType To) { +bool Sema::DiscardingCFIUncheckedCallee(QualType From, QualType To) const { + From = Context.getCanonicalType(From); + To = Context.getCanonicalType(To); QualType MaybePointee = From->getPointeeType(); if (!MaybePointee.isNull() && MaybePointee->getAs<FunctionType>()) From = MaybePointee; @@ -12392,25 +12387,10 @@ static CFIUncheckedCalleeChange AdjustingCFIUncheckedCallee(QualType From, if (const auto *ToFn = To->getAs<FunctionType>()) { if (FromFn->getCFIUncheckedCalleeAttr() && !ToFn->getCFIUncheckedCalleeAttr()) - return Discarding; - if (!FromFn->getCFIUncheckedCalleeAttr() && - ToFn->getCFIUncheckedCalleeAttr()) - return Adding; + return true; } } - return None; -} - -bool Sema::DiscardingCFIUncheckedCallee(QualType From, QualType To) const { - From = Context.getCanonicalType(From); - To = Context.getCanonicalType(To); - return ::AdjustingCFIUncheckedCallee(From, To) == Discarding; -} - -bool Sema::AddingCFIUncheckedCallee(QualType From, QualType To) const { - From = Context.getCanonicalType(From); - To = Context.getCanonicalType(To); - return ::AdjustingCFIUncheckedCallee(From, To) == Adding; + return false; } void Sema::CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC, diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 2a485da..96d5142 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -21,6 +21,7 @@ #include "clang/AST/Expr.h" #include "clang/AST/HLSLResource.h" #include "clang/AST/Type.h" +#include "clang/AST/TypeBase.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/DiagnosticSema.h" @@ -3432,6 +3433,11 @@ static void BuildFlattenedTypeList(QualType BaseTy, List.insert(List.end(), VT->getNumElements(), VT->getElementType()); continue; } + if (const auto *MT = dyn_cast<ConstantMatrixType>(T)) { + List.insert(List.end(), MT->getNumElementsFlattened(), + MT->getElementType()); + continue; + } if (const auto *RD = T->getAsCXXRecordDecl()) { if (RD->isStandardLayout()) RD = RD->getStandardLayoutBaseWithFields(); @@ -4230,6 +4236,32 @@ class InitListTransformer { } return true; } + if (auto *MTy = Ty->getAs<ConstantMatrixType>()) { + unsigned Rows = MTy->getNumRows(); + unsigned Cols = MTy->getNumColumns(); + QualType ElemTy = MTy->getElementType(); + + for (unsigned C = 0; C < Cols; ++C) { + for (unsigned R = 0; R < Rows; ++R) { + // row index literal + Expr *RowIdx = IntegerLiteral::Create( + Ctx, llvm::APInt(Ctx.getIntWidth(Ctx.IntTy), R), Ctx.IntTy, + E->getBeginLoc()); + // column index literal + Expr *ColIdx = IntegerLiteral::Create( + Ctx, llvm::APInt(Ctx.getIntWidth(Ctx.IntTy), C), Ctx.IntTy, + E->getBeginLoc()); + ExprResult ElExpr = S.CreateBuiltinMatrixSubscriptExpr( + E, RowIdx, ColIdx, E->getEndLoc()); + if (ElExpr.isInvalid()) + return false; + if (!castInitializer(ElExpr.get())) + return false; + ElExpr.get()->setType(ElemTy); + } + } + return true; + } if (auto *ArrTy = dyn_cast<ConstantArrayType>(Ty.getTypePtr())) { uint64_t Size = ArrTy->getZExtSize(); @@ -4283,14 +4315,17 @@ class InitListTransformer { return *(ArgIt++); llvm::SmallVector<Expr *> Inits; - assert(!isa<MatrixType>(Ty) && "Matrix types not yet supported in HLSL"); Ty = Ty.getDesugaredType(Ctx); - if (Ty->isVectorType() || Ty->isConstantArrayType()) { + if (Ty->isVectorType() || Ty->isConstantArrayType() || + Ty->isConstantMatrixType()) { QualType ElTy; uint64_t Size = 0; if (auto *ATy = Ty->getAs<VectorType>()) { ElTy = ATy->getElementType(); Size = ATy->getNumElements(); + } else if (auto *CMTy = Ty->getAs<ConstantMatrixType>()) { + ElTy = CMTy->getElementType(); + Size = CMTy->getNumElementsFlattened(); } else { auto *VTy = cast<ConstantArrayType>(Ty.getTypePtr()); ElTy = VTy->getElementType(); diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 7debe33..073010d 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -17,6 +17,7 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/IgnoreExpr.h" +#include "clang/AST/TypeBase.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/Specifiers.h" @@ -403,6 +404,9 @@ class InitListChecker { unsigned &Index, InitListExpr *StructuredList, unsigned &StructuredIndex); + void CheckMatrixType(const InitializedEntity &Entity, InitListExpr *IList, + QualType DeclType, unsigned &Index, + InitListExpr *StructuredList, unsigned &StructuredIndex); void CheckVectorType(const InitializedEntity &Entity, InitListExpr *IList, QualType DeclType, unsigned &Index, InitListExpr *StructuredList, @@ -1004,7 +1008,8 @@ InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity, return; if (ElementEntity.getKind() == InitializedEntity::EK_ArrayElement || - ElementEntity.getKind() == InitializedEntity::EK_VectorElement) + ElementEntity.getKind() == InitializedEntity::EK_VectorElement || + ElementEntity.getKind() == InitializedEntity::EK_MatrixElement) ElementEntity.setElementIndex(Init); if (Init >= NumInits && (ILE->hasArrayFiller() || SkipEmptyInitChecks)) @@ -1274,6 +1279,7 @@ static void warnBracedScalarInit(Sema &S, const InitializedEntity &Entity, switch (Entity.getKind()) { case InitializedEntity::EK_VectorElement: + case InitializedEntity::EK_MatrixElement: case InitializedEntity::EK_ComplexElement: case InitializedEntity::EK_ArrayElement: case InitializedEntity::EK_Parameter: @@ -1373,11 +1379,12 @@ void InitListChecker::CheckExplicitInitList(const InitializedEntity &Entity, SemaRef.Diag(IList->getInit(Index)->getBeginLoc(), DK) << T << IList->getInit(Index)->getSourceRange(); } else { - int initKind = T->isArrayType() ? 0 : - T->isVectorType() ? 1 : - T->isScalarType() ? 2 : - T->isUnionType() ? 3 : - 4; + int initKind = T->isArrayType() ? 0 + : T->isVectorType() ? 1 + : T->isMatrixType() ? 2 + : T->isScalarType() ? 3 + : T->isUnionType() ? 4 + : 5; unsigned DK = ExtraInitsIsError ? diag::err_excess_initializers : diag::ext_excess_initializers; @@ -1431,6 +1438,9 @@ void InitListChecker::CheckListElementTypes(const InitializedEntity &Entity, } else if (DeclType->isVectorType()) { CheckVectorType(Entity, IList, DeclType, Index, StructuredList, StructuredIndex); + } else if (DeclType->isMatrixType()) { + CheckMatrixType(Entity, IList, DeclType, Index, StructuredList, + StructuredIndex); } else if (const RecordDecl *RD = DeclType->getAsRecordDecl()) { auto Bases = CXXRecordDecl::base_class_const_range(CXXRecordDecl::base_class_const_iterator(), @@ -1878,6 +1888,37 @@ void InitListChecker::CheckReferenceType(const InitializedEntity &Entity, AggrDeductionCandidateParamTypes->push_back(DeclType); } +void InitListChecker::CheckMatrixType(const InitializedEntity &Entity, + InitListExpr *IList, QualType DeclType, + unsigned &Index, + InitListExpr *StructuredList, + unsigned &StructuredIndex) { + if (!SemaRef.getLangOpts().HLSL) + return; + + const ConstantMatrixType *MT = DeclType->castAs<ConstantMatrixType>(); + QualType ElemTy = MT->getElementType(); + const unsigned MaxElts = MT->getNumElementsFlattened(); + + unsigned NumEltsInit = 0; + InitializedEntity ElemEnt = + InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity); + + while (NumEltsInit < MaxElts && Index < IList->getNumInits()) { + // Not a sublist: just consume directly. + ElemEnt.setElementIndex(Index); + CheckSubElementType(ElemEnt, IList, ElemTy, Index, StructuredList, + StructuredIndex); + ++NumEltsInit; + } + + // For HLSL The error for this case is handled in SemaHLSL's initializer + // list diagnostics, That means the execution should require NumEltsInit + // to equal Max initializers. In other words execution should never + // reach this point if this condition is not true". + assert(NumEltsInit == MaxElts && "NumEltsInit must equal MaxElts"); +} + void InitListChecker::CheckVectorType(const InitializedEntity &Entity, InitListExpr *IList, QualType DeclType, unsigned &Index, @@ -3640,6 +3681,9 @@ InitializedEntity::InitializedEntity(ASTContext &Context, unsigned Index, } else if (const VectorType *VT = Parent.getType()->getAs<VectorType>()) { Kind = EK_VectorElement; Type = VT->getElementType(); + } else if (const MatrixType *MT = Parent.getType()->getAs<MatrixType>()) { + Kind = EK_MatrixElement; + Type = MT->getElementType(); } else { const ComplexType *CT = Parent.getType()->getAs<ComplexType>(); assert(CT && "Unexpected type"); @@ -3688,6 +3732,7 @@ DeclarationName InitializedEntity::getName() const { case EK_Delegating: case EK_ArrayElement: case EK_VectorElement: + case EK_MatrixElement: case EK_ComplexElement: case EK_BlockElement: case EK_LambdaToBlockConversionBlockElement: @@ -3721,6 +3766,7 @@ ValueDecl *InitializedEntity::getDecl() const { case EK_Delegating: case EK_ArrayElement: case EK_VectorElement: + case EK_MatrixElement: case EK_ComplexElement: case EK_BlockElement: case EK_LambdaToBlockConversionBlockElement: @@ -3754,6 +3800,7 @@ bool InitializedEntity::allowsNRVO() const { case EK_Delegating: case EK_ArrayElement: case EK_VectorElement: + case EK_MatrixElement: case EK_ComplexElement: case EK_BlockElement: case EK_LambdaToBlockConversionBlockElement: @@ -3793,6 +3840,9 @@ unsigned InitializedEntity::dumpImpl(raw_ostream &OS) const { case EK_Delegating: OS << "Delegating"; break; case EK_ArrayElement: OS << "ArrayElement " << Index; break; case EK_VectorElement: OS << "VectorElement " << Index; break; + case EK_MatrixElement: + OS << "MatrixElement " << Index; + break; case EK_ComplexElement: OS << "ComplexElement " << Index; break; case EK_BlockElement: OS << "Block"; break; case EK_LambdaToBlockConversionBlockElement: @@ -6030,7 +6080,7 @@ static void TryOrBuildParenListInitialization( Sequence.SetFailed(InitializationSequence::FK_ParenthesizedListInitFailed); if (!VerifyOnly) { QualType T = Entity.getType(); - int InitKind = T->isArrayType() ? 0 : T->isUnionType() ? 3 : 4; + int InitKind = T->isArrayType() ? 0 : T->isUnionType() ? 4 : 5; SourceRange ExcessInitSR(Args[EntityIndexToProcess]->getBeginLoc(), Args.back()->getEndLoc()); S.Diag(Kind.getLocation(), diag::err_excess_initializers) @@ -6823,7 +6873,8 @@ void InitializationSequence::InitializeFrom(Sema &S, // For HLSL ext vector types we allow list initialization behavior for C++ // functional cast expressions which look like constructor syntax. This is // accomplished by converting initialization arguments to InitListExpr. - if (S.getLangOpts().HLSL && Args.size() > 1 && DestType->isExtVectorType() && + if (S.getLangOpts().HLSL && Args.size() > 1 && + (DestType->isExtVectorType() || DestType->isConstantMatrixType()) && (SourceType.isNull() || !Context.hasSameUnqualifiedType(SourceType, DestType))) { InitListExpr *ILE = new (Context) @@ -6988,6 +7039,7 @@ static AssignmentAction getAssignmentAction(const InitializedEntity &Entity, case InitializedEntity::EK_Binding: case InitializedEntity::EK_ArrayElement: case InitializedEntity::EK_VectorElement: + case InitializedEntity::EK_MatrixElement: case InitializedEntity::EK_ComplexElement: case InitializedEntity::EK_BlockElement: case InitializedEntity::EK_LambdaToBlockConversionBlockElement: @@ -7013,6 +7065,7 @@ static bool shouldBindAsTemporary(const InitializedEntity &Entity) { case InitializedEntity::EK_Base: case InitializedEntity::EK_Delegating: case InitializedEntity::EK_VectorElement: + case InitializedEntity::EK_MatrixElement: case InitializedEntity::EK_ComplexElement: case InitializedEntity::EK_Exception: case InitializedEntity::EK_BlockElement: @@ -7043,6 +7096,7 @@ static bool shouldDestroyEntity(const InitializedEntity &Entity) { case InitializedEntity::EK_Base: case InitializedEntity::EK_Delegating: case InitializedEntity::EK_VectorElement: + case InitializedEntity::EK_MatrixElement: case InitializedEntity::EK_ComplexElement: case InitializedEntity::EK_BlockElement: case InitializedEntity::EK_LambdaToBlockConversionBlockElement: @@ -7096,6 +7150,7 @@ static SourceLocation getInitializationLoc(const InitializedEntity &Entity, case InitializedEntity::EK_Base: case InitializedEntity::EK_Delegating: case InitializedEntity::EK_VectorElement: + case InitializedEntity::EK_MatrixElement: case InitializedEntity::EK_ComplexElement: case InitializedEntity::EK_BlockElement: case InitializedEntity::EK_LambdaToBlockConversionBlockElement: @@ -7845,11 +7900,13 @@ ExprResult InitializationSequence::Perform(Sema &S, ExprResult CurInit((Expr *)nullptr); SmallVector<Expr*, 4> ArrayLoopCommonExprs; - // HLSL allows vector initialization to function like list initialization, but - // use the syntax of a C++-like constructor. - bool IsHLSLVectorInit = S.getLangOpts().HLSL && DestType->isExtVectorType() && - isa<InitListExpr>(Args[0]); - (void)IsHLSLVectorInit; + // HLSL allows vector/matrix initialization to function like list + // initialization, but use the syntax of a C++-like constructor. + bool IsHLSLVectorOrMatrixInit = + S.getLangOpts().HLSL && + (DestType->isExtVectorType() || DestType->isConstantMatrixType()) && + isa<InitListExpr>(Args[0]); + (void)IsHLSLVectorOrMatrixInit; // For initialization steps that start with a single initializer, // grab the only argument out the Args and place it into the "current" @@ -7888,7 +7945,7 @@ ExprResult InitializationSequence::Perform(Sema &S, case SK_StdInitializerList: case SK_OCLSamplerInit: case SK_OCLZeroOpaqueType: { - assert(Args.size() == 1 || IsHLSLVectorInit); + assert(Args.size() == 1 || IsHLSLVectorOrMatrixInit); CurInit = Args[0]; if (!CurInit.get()) return ExprError(); break; @@ -9105,7 +9162,7 @@ bool InitializationSequence::Diagnose(Sema &S, << R; else S.Diag(Kind.getLocation(), diag::err_excess_initializers) - << /*scalar=*/2 << R; + << /*scalar=*/3 << R; break; } diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp index 1880cec..67c554c 100644 --- a/clang/lib/Sema/SemaObjCProperty.cpp +++ b/clang/lib/Sema/SemaObjCProperty.cpp @@ -1041,7 +1041,7 @@ RedeclarePropertyAccessor(ASTContext &Context, ObjCImplementationDecl *Impl, Decl->getSelector(), Decl->getReturnType(), Decl->getReturnTypeSourceInfo(), Impl, Decl->isInstanceMethod(), Decl->isVariadic(), Decl->isPropertyAccessor(), - /* isSynthesized*/ true, Decl->isImplicit(), Decl->isDefined(), + /*isSynthesizedAccessorStub=*/true, Decl->isImplicit(), Decl->isDefined(), Decl->getImplementationControl(), Decl->hasRelatedResultType()); ImplDecl->getMethodFamily(); if (Decl->hasAttrs()) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 1f25111..37f3511 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -2532,15 +2532,12 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType, SCS.setToType(2, FromType); - // If we have not converted the argument type to the parameter type, - // this is a bad conversion sequence, unless we're resolving an overload in C. - // - // Permit conversions from a function without `cfi_unchecked_callee` to a - // function with `cfi_unchecked_callee`. - if (CanonFrom == CanonTo || S.AddingCFIUncheckedCallee(CanonFrom, CanonTo)) + if (CanonFrom == CanonTo) return true; - if ((S.getLangOpts().CPlusPlus || !InOverloadResolution)) + // If we have not converted the argument type to the parameter type, + // this is a bad conversion sequence, unless we're resolving an overload in C. + if (S.getLangOpts().CPlusPlus || !InOverloadResolution) return false; ExprResult ER = ExprResult{From}; diff --git a/clang/lib/Sema/SemaRISCV.cpp b/clang/lib/Sema/SemaRISCV.cpp index b5f91a3..75dba80 100644 --- a/clang/lib/Sema/SemaRISCV.cpp +++ b/clang/lib/Sema/SemaRISCV.cpp @@ -664,6 +664,80 @@ bool SemaRISCV::CheckBuiltinFunctionCall(const TargetInfo &TI, return CheckVSetVL(1, 2); case RISCVVector::BI__builtin_rvv_vsetvlimax: return CheckVSetVL(0, 1); + case RISCVVector::BI__builtin_rvv_sf_vsettnt: + case RISCVVector::BI__builtin_rvv_sf_vsettm: + case RISCVVector::BI__builtin_rvv_sf_vsettn: + case RISCVVector::BI__builtin_rvv_sf_vsettk: + return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 3) || + SemaRef.BuiltinConstantArgRange(TheCall, 2, 1, 3); + case RISCVVector::BI__builtin_rvv_sf_mm_f_f_w1: + case RISCVVector::BI__builtin_rvv_sf_mm_f_f_w2: + case RISCVVector::BI__builtin_rvv_sf_mm_e5m2_e4m3_w4: + case RISCVVector::BI__builtin_rvv_sf_mm_e5m2_e5m2_w4: + case RISCVVector::BI__builtin_rvv_sf_mm_e4m3_e4m3_w4: + case RISCVVector::BI__builtin_rvv_sf_mm_e4m3_e5m2_w4: + case RISCVVector::BI__builtin_rvv_sf_mm_u_u_w4: + case RISCVVector::BI__builtin_rvv_sf_mm_u_s_w4: + case RISCVVector::BI__builtin_rvv_sf_mm_s_u_w4: + case RISCVVector::BI__builtin_rvv_sf_mm_s_s_w4: { + QualType Arg1Type = TheCall->getArg(1)->getType(); + ASTContext::BuiltinVectorTypeInfo Info = + SemaRef.Context.getBuiltinVectorTypeInfo( + Arg1Type->castAs<BuiltinType>()); + unsigned EltSize = SemaRef.Context.getTypeSize(Info.ElementType); + llvm::APSInt Result; + + // We can't check the value of a dependent argument. + Expr *Arg = TheCall->getArg(0); + if (Arg->isTypeDependent() || Arg->isValueDependent()) + return false; + + // Check constant-ness first. + if (SemaRef.BuiltinConstantArg(TheCall, 0, Result)) + return true; + + // For TEW = 32, mtd can only be 0, 4, 8, 12. + // For TEW = 64, mtd can only be 0, 2, 4, 6, 8, 10, 12, 14. + // Only `sf_mm_f_f_w1` and `sf_mm_f_f_w2` might have TEW = 64. + if ((BuiltinID == RISCVVector::BI__builtin_rvv_sf_mm_f_f_w1 && + EltSize == 64) || + (BuiltinID == RISCVVector::BI__builtin_rvv_sf_mm_f_f_w2 && + EltSize == 32)) + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 15) || + SemaRef.BuiltinConstantArgMultiple(TheCall, 0, 2); + return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 15) || + SemaRef.BuiltinConstantArgMultiple(TheCall, 0, 4); + } + case RISCVVector::BI__builtin_rvv_sf_vtzero_t: { + llvm::APSInt Log2SEWResult; + llvm::APSInt TWidenResult; + if (SemaRef.BuiltinConstantArg(TheCall, 3, Log2SEWResult) || + SemaRef.BuiltinConstantArg(TheCall, 4, TWidenResult)) + return true; + + int Log2SEW = Log2SEWResult.getSExtValue(); + int TWiden = TWidenResult.getSExtValue(); + + // 3 <= LogSEW <= 6 + if (SemaRef.BuiltinConstantArgRange(TheCall, 3, 3, 6)) + return true; + + // TWiden + if (TWiden != 1 && TWiden != 2 && TWiden != 4) + return Diag(TheCall->getBeginLoc(), + diag::err_riscv_builtin_invalid_twiden); + + int TEW = (1 << Log2SEW) * TWiden; + + // For TEW = 8, mtd can be 0~15. + // For TEW = 16 or 64, mtd can only be 0, 2, 4, 6, 8, 10, 12, 14. + // For TEW = 32, mtd can only be 0, 4, 8, 12. + if (SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 15)) + return true; + if (TEW == 16 || TEW == 64) + return SemaRef.BuiltinConstantArgMultiple(TheCall, 0, 2); + return SemaRef.BuiltinConstantArgMultiple(TheCall, 0, 4); + } case RISCVVector::BI__builtin_rvv_vget_v: { ASTContext::BuiltinVectorTypeInfo ResVecInfo = Context.getBuiltinVectorTypeInfo(cast<BuiltinType>( |
