aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/CheckExprLifetime.cpp1
-rw-r--r--clang/lib/Sema/SemaChecking.cpp30
-rw-r--r--clang/lib/Sema/SemaHLSL.cpp39
-rw-r--r--clang/lib/Sema/SemaInit.cpp87
-rw-r--r--clang/lib/Sema/SemaObjCProperty.cpp2
-rw-r--r--clang/lib/Sema/SemaOverload.cpp11
-rw-r--r--clang/lib/Sema/SemaRISCV.cpp74
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>(