301 changes: 301 additions & 0 deletions clang/lib/Headers/avx10_2_512satcvtintrin.h

Large diffs are not rendered by default.

444 changes: 444 additions & 0 deletions clang/lib/Headers/avx10_2satcvtintrin.h

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions clang/lib/Headers/immintrin.h
Original file line number Diff line number Diff line change
Expand Up @@ -651,11 +651,13 @@ _storebe_i64(void * __P, long long __D) {
#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX10_2__)
#include <avx10_2minmaxintrin.h>
#include <avx10_2niintrin.h>
#include <avx10_2satcvtintrin.h>
#endif

#if !defined(__SCE__) || __has_feature(modules) || defined(__AVX10_2_512__)
#include <avx10_2_512minmaxintrin.h>
#include <avx10_2_512niintrin.h>
#include <avx10_2_512satcvtintrin.h>
#endif

#if !defined(__SCE__) || __has_feature(modules) || defined(__ENQCMD__)
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/Headers/ptrauth.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ typedef enum {
The extra data is always 0. */
ptrauth_key_cxx_vtable_pointer = ptrauth_key_process_independent_data,

/* The key used to sign pointers in ELF .init_array/.fini_array. */
ptrauth_key_init_fini_pointer = ptrauth_key_process_independent_code,

/* Other pointers signed under the ABI use private ABI rules. */

} ptrauth_key;
Expand Down Expand Up @@ -247,6 +250,9 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
[[clang::ptrauth_vtable_pointer(key, address_discrimination, \
extra_discrimination)]]

/* The value is ptrauth_string_discriminator("init_fini") */
#define __ptrauth_init_fini_discriminator 0xd9d4

#else

#define ptrauth_strip(__value, __key) \
Expand Down
71 changes: 17 additions & 54 deletions clang/lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,27 +314,24 @@ void Parser::ParseGNUAttributes(ParsedAttributes &Attrs,
}

/// Determine whether the given attribute has an identifier argument.
static bool attributeHasIdentifierArg(const IdentifierInfo &II,
static bool attributeHasIdentifierArg(const llvm::Triple &T,
const IdentifierInfo &II,
ParsedAttr::Syntax Syntax,
IdentifierInfo *ScopeName) {
std::string FullName =
AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax);
#define CLANG_ATTR_IDENTIFIER_ARG_LIST
return llvm::StringSwitch<bool>(FullName)
return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
#include "clang/Parse/AttrParserStringSwitches.inc"
.Default(false);
#undef CLANG_ATTR_IDENTIFIER_ARG_LIST
}

/// Determine whether the given attribute has an identifier argument.
/// Determine whether the given attribute has string arguments.
static ParsedAttributeArgumentsProperties
attributeStringLiteralListArg(const llvm::Triple &T, const IdentifierInfo &II,
ParsedAttr::Syntax Syntax,
IdentifierInfo *ScopeName) {
std::string FullName =
AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax);
#define CLANG_ATTR_STRING_LITERAL_ARG_LIST
return llvm::StringSwitch<uint32_t>(FullName)
return llvm::StringSwitch<uint32_t>(normalizeAttrName(II.getName()))
#include "clang/Parse/AttrParserStringSwitches.inc"
.Default(0);
#undef CLANG_ATTR_STRING_LITERAL_ARG_LIST
Expand All @@ -344,10 +341,8 @@ attributeStringLiteralListArg(const llvm::Triple &T, const IdentifierInfo &II,
static bool attributeHasVariadicIdentifierArg(const IdentifierInfo &II,
ParsedAttr::Syntax Syntax,
IdentifierInfo *ScopeName) {
std::string FullName =
AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax);
#define CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
return llvm::StringSwitch<bool>(FullName)
return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
#include "clang/Parse/AttrParserStringSwitches.inc"
.Default(false);
#undef CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
Expand All @@ -357,10 +352,8 @@ static bool attributeHasVariadicIdentifierArg(const IdentifierInfo &II,
static bool attributeTreatsKeywordThisAsIdentifier(const IdentifierInfo &II,
ParsedAttr::Syntax Syntax,
IdentifierInfo *ScopeName) {
std::string FullName =
AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax);
#define CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
return llvm::StringSwitch<bool>(FullName)
return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
#include "clang/Parse/AttrParserStringSwitches.inc"
.Default(false);
#undef CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
Expand All @@ -370,10 +363,8 @@ static bool attributeTreatsKeywordThisAsIdentifier(const IdentifierInfo &II,
static bool attributeAcceptsExprPack(const IdentifierInfo &II,
ParsedAttr::Syntax Syntax,
IdentifierInfo *ScopeName) {
std::string FullName =
AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax);
#define CLANG_ATTR_ACCEPTS_EXPR_PACK
return llvm::StringSwitch<bool>(FullName)
return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
#include "clang/Parse/AttrParserStringSwitches.inc"
.Default(false);
#undef CLANG_ATTR_ACCEPTS_EXPR_PACK
Expand All @@ -383,53 +374,31 @@ static bool attributeAcceptsExprPack(const IdentifierInfo &II,
static bool attributeIsTypeArgAttr(const IdentifierInfo &II,
ParsedAttr::Syntax Syntax,
IdentifierInfo *ScopeName) {
std::string FullName =
AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax);
#define CLANG_ATTR_TYPE_ARG_LIST
return llvm::StringSwitch<bool>(FullName)
return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
#include "clang/Parse/AttrParserStringSwitches.inc"
.Default(false);
#undef CLANG_ATTR_TYPE_ARG_LIST
}

/// Determine whether the given attribute takes identifier arguments.
/// Determine whether the given attribute takes a strict identifier argument.
static bool attributeHasStrictIdentifierArgs(const IdentifierInfo &II,
ParsedAttr::Syntax Syntax,
IdentifierInfo *ScopeName) {
std::string FullName =
AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax);
#define CLANG_ATTR_STRICT_IDENTIFIER_ARG_AT_INDEX_LIST
return (llvm::StringSwitch<uint64_t>(FullName)
#include "clang/Parse/AttrParserStringSwitches.inc"
.Default(0)) != 0;
#undef CLANG_ATTR_STRICT_IDENTIFIER_ARG_AT_INDEX_LIST
}

/// Determine whether the given attribute takes an identifier argument at a
/// specific index
static bool attributeHasStrictIdentifierArgAtIndex(const IdentifierInfo &II,
ParsedAttr::Syntax Syntax,
IdentifierInfo *ScopeName,
size_t argIndex) {
std::string FullName =
AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax);
#define CLANG_ATTR_STRICT_IDENTIFIER_ARG_AT_INDEX_LIST
return (llvm::StringSwitch<uint64_t>(FullName)
#define CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST
return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
#include "clang/Parse/AttrParserStringSwitches.inc"
.Default(0)) &
(1ull << argIndex);
#undef CLANG_ATTR_STRICT_IDENTIFIER_ARG_AT_INDEX_LIST
.Default(false);
#undef CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST
}

/// Determine whether the given attribute requires parsing its arguments
/// in an unevaluated context or not.
static bool attributeParsedArgsUnevaluated(const IdentifierInfo &II,
ParsedAttr::Syntax Syntax,
IdentifierInfo *ScopeName) {
std::string FullName =
AttributeCommonInfo::normalizeFullNameWithSyntax(&II, ScopeName, Syntax);
#define CLANG_ATTR_ARG_CONTEXT_LIST
return llvm::StringSwitch<bool>(FullName)
return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
#include "clang/Parse/AttrParserStringSwitches.inc"
.Default(false);
#undef CLANG_ATTR_ARG_CONTEXT_LIST
Expand Down Expand Up @@ -575,7 +544,8 @@ unsigned Parser::ParseAttributeArgsCommon(
// If this attribute wants an 'identifier' argument, make it so.
bool IsIdentifierArg =
AttributeHasVariadicIdentifierArg ||
attributeHasIdentifierArg(*AttrName, Form.getSyntax(), ScopeName);
attributeHasIdentifierArg(getTargetInfo().getTriple(), *AttrName,
Form.getSyntax(), ScopeName);
ParsedAttr::Kind AttrKind =
ParsedAttr::getParsedKind(AttrName, ScopeName, Form.getSyntax());

Expand Down Expand Up @@ -619,13 +589,6 @@ unsigned Parser::ParseAttributeArgsCommon(
if (ChangeKWThisToIdent && Tok.is(tok::kw_this))
Tok.setKind(tok::identifier);

if (Tok.is(tok::identifier) &&
attributeHasStrictIdentifierArgAtIndex(
*AttrName, Form.getSyntax(), ScopeName, ArgExprs.size())) {
ArgExprs.push_back(ParseIdentifierLoc());
continue;
}

ExprResult ArgExpr;
if (Tok.is(tok::identifier)) {
ArgExprs.push_back(ParseIdentifierLoc());
Expand Down
8 changes: 7 additions & 1 deletion clang/lib/Parse/ParseOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3175,7 +3175,6 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
case OMPC_simdlen:
case OMPC_collapse:
case OMPC_ordered:
case OMPC_num_teams:
case OMPC_thread_limit:
case OMPC_priority:
case OMPC_grainsize:
Expand Down Expand Up @@ -3332,6 +3331,13 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
? ParseOpenMPSimpleClause(CKind, WrongDirective)
: ParseOpenMPClause(CKind, WrongDirective);
break;
case OMPC_num_teams:
if (!FirstClause) {
Diag(Tok, diag::err_omp_more_one_clause)
<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
ErrorFound = true;
}
[[fallthrough]];
case OMPC_private:
case OMPC_firstprivate:
case OMPC_lastprivate:
Expand Down
8 changes: 2 additions & 6 deletions clang/lib/Sema/SemaBoundsSafety.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,8 @@ enum class CountedByInvalidPointeeTypeKind {
VALID,
};

bool Sema::CheckCountedByAttrOnField(
FieldDecl *FD, Expr *E,
llvm::SmallVectorImpl<TypeCoupledDeclRefInfo> &Decls, bool CountInBytes,
bool OrNull) {
bool Sema::CheckCountedByAttrOnField(FieldDecl *FD, Expr *E, bool CountInBytes,
bool OrNull) {
// Check the context the attribute is used in

unsigned Kind = getCountAttrKind(CountInBytes, OrNull);
Expand Down Expand Up @@ -185,8 +183,6 @@ bool Sema::CheckCountedByAttrOnField(
return true;
}
}

Decls.push_back(TypeCoupledDeclRefInfo(CountFD, /*IsDref*/ false));
return false;
}

Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Sema/SemaCoroutine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -838,7 +838,8 @@ ExprResult Sema::BuildOperatorCoawaitLookupExpr(Scope *S, SourceLocation Loc) {
Expr *CoawaitOp = UnresolvedLookupExpr::Create(
Context, /*NamingClass*/ nullptr, NestedNameSpecifierLoc(),
DeclarationNameInfo(OpName, Loc), /*RequiresADL*/ true, Functions.begin(),
Functions.end(), /*KnownDependent=*/false);
Functions.end(), /*KnownDependent=*/false,
/*KnownInstantiationDependent=*/false);
assert(CoawaitOp);
return CoawaitOp;
}
Expand Down
9 changes: 5 additions & 4 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1219,7 +1219,7 @@ Sema::NameClassification Sema::ClassifyName(Scope *S, CXXScopeSpec &SS,
return NameClassification::OverloadSet(UnresolvedLookupExpr::Create(
Context, Result.getNamingClass(), SS.getWithLocInContext(Context),
Result.getLookupNameInfo(), ADL, Result.begin(), Result.end(),
/*KnownDependent=*/false));
/*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
}

ExprResult
Expand Down Expand Up @@ -7964,8 +7964,9 @@ NamedDecl *Sema::ActOnVariableDeclarator(
D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous));
} else {
// If this is an explicit specialization of a static data member, check it.
if (IsMemberSpecialization && !IsVariableTemplateSpecialization &&
!NewVD->isInvalidDecl() && CheckMemberSpecialization(NewVD, Previous))
if (IsMemberSpecialization && !IsVariableTemplate &&
!IsVariableTemplateSpecialization && !NewVD->isInvalidDecl() &&
CheckMemberSpecialization(NewVD, Previous))
NewVD->setInvalidDecl();

// Merge the decl with the existing one if appropriate.
Expand Down Expand Up @@ -10466,7 +10467,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
Previous))
NewFD->setInvalidDecl();
}
} else if (isMemberSpecialization && isa<CXXMethodDecl>(NewFD)) {
} else if (isMemberSpecialization && !FunctionTemplate) {
if (CheckMemberSpecialization(NewFD, Previous))
NewFD->setInvalidDecl();
}
Expand Down
3 changes: 1 addition & 2 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5898,8 +5898,7 @@ static void handleCountedByAttrField(Sema &S, Decl *D, const ParsedAttr &AL) {
llvm_unreachable("unexpected counted_by family attribute");
}

llvm::SmallVector<TypeCoupledDeclRefInfo, 1> Decls;
if (S.CheckCountedByAttrOnField(FD, CountExpr, Decls, CountInBytes, OrNull))
if (S.CheckCountedByAttrOnField(FD, CountExpr, CountInBytes, OrNull))
return;

QualType CAT = S.BuildCountAttributedArrayOrPointerType(
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Sema/SemaDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1289,7 +1289,7 @@ static bool checkTupleLikeDecomposition(Sema &S,
S.Context, nullptr, NestedNameSpecifierLoc(), SourceLocation(),
DeclarationNameInfo(GetDN, Loc), /*RequiresADL=*/true, &Args,
UnresolvedSetIterator(), UnresolvedSetIterator(),
/*KnownDependent=*/false);
/*KnownDependent=*/false, /*KnownInstantiationDependent=*/false);

Expr *Arg = E.get();
E = S.BuildCallExpr(nullptr, Get, Loc, Arg, Loc);
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3188,7 +3188,7 @@ ExprResult Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
UnresolvedLookupExpr *ULE = UnresolvedLookupExpr::Create(
Context, R.getNamingClass(), SS.getWithLocInContext(Context),
R.getLookupNameInfo(), NeedsADL, R.begin(), R.end(),
/*KnownDependent=*/false);
/*KnownDependent=*/false, /*KnownInstantiationDependent=*/false);

return ULE;
}
Expand Down Expand Up @@ -3652,7 +3652,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
// Fast path for a single digit (which is quite common). A single digit
// cannot have a trigraph, escaped newline, radix prefix, or suffix.
if (Tok.getLength() == 1 || Tok.getKind() == tok::binary_data) {
const char Val = PP.getSpellingOfSingleCharacterNumericConstant(Tok);
const uint8_t Val = PP.getSpellingOfSingleCharacterNumericConstant(Tok);
return ActOnIntegerConstant(Tok.getLocation(), Val);
}

Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Sema/SemaExprMember.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,8 @@ ExprResult Sema::BuildPossibleImplicitMemberExpr(
return UnresolvedLookupExpr::Create(
Context, R.getNamingClass(), SS.getWithLocInContext(Context),
TemplateKWLoc, R.getLookupNameInfo(), /*RequiresADL=*/false,
TemplateArgs, R.begin(), R.end(), /*KnownDependent=*/true);
TemplateArgs, R.begin(), R.end(), /*KnownDependent=*/true,
/*KnownInstantiationDependent=*/true);

case IMA_Error_StaticOrExplicitContext:
case IMA_Error_Unrelated:
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Sema/SemaLambda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1021,6 +1021,8 @@ void Sema::CompleteLambdaCallOperator(
getGenericLambdaTemplateParameterList(LSI, *this);

DeclContext *DC = Method->getLexicalDeclContext();
// DeclContext::addDecl() assumes that the DeclContext we're adding to is the
// lexical context of the Method. Do so.
Method->setLexicalDeclContext(LSI->Lambda);
if (TemplateParams) {
FunctionTemplateDecl *TemplateMethod =
Expand Down Expand Up @@ -1105,6 +1107,8 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,

CXXMethodDecl *Method = CreateLambdaCallOperator(Intro.Range, Class);
LSI->CallOperator = Method;
// Temporarily set the lexical declaration context to the current
// context, so that the Scope stack matches the lexical nesting.
Method->setLexicalDeclContext(CurContext);

PushDeclContext(CurScope, Method);
Expand Down
97 changes: 77 additions & 20 deletions clang/lib/Sema/SemaOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13034,13 +13034,36 @@ StmtResult SemaOpenMP::ActOnOpenMPTargetUpdateDirective(
Clauses, AStmt);
}

/// This checks whether a \p ClauseType clause \p C has at most \p Max
/// expression. If not, a diag of number \p Diag will be emitted.
template <typename ClauseType>
static bool checkNumExprsInClause(SemaBase &SemaRef,
ArrayRef<OMPClause *> Clauses,
unsigned MaxNum, unsigned Diag) {
auto ClauseItr = llvm::find_if(Clauses, llvm::IsaPred<ClauseType>);
if (ClauseItr == Clauses.end())
return true;
const auto *C = cast<ClauseType>(*ClauseItr);
auto VarList = C->getVarRefs();
if (VarList.size() > MaxNum) {
SemaRef.Diag(VarList[MaxNum]->getBeginLoc(), Diag)
<< getOpenMPClauseName(C->getClauseKind());
return false;
}
return true;
}

StmtResult SemaOpenMP::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
Stmt *AStmt,
SourceLocation StartLoc,
SourceLocation EndLoc) {
if (!AStmt)
return StmtError();

if (!checkNumExprsInClause<OMPNumTeamsClause>(
*this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed))
return StmtError();

// Report affected OpenMP target offloading behavior when in HIP lang-mode.
if (getLangOpts().HIP && (DSAStack->getParentDirective() == OMPD_target))
Diag(StartLoc, diag::warn_hip_omp_target_directives);
Expand Down Expand Up @@ -13815,6 +13838,14 @@ StmtResult SemaOpenMP::ActOnOpenMPTargetTeamsDirective(
return StmtError();
}

unsigned ClauseMaxNumExprs = HasBareClause ? 3 : 1;
unsigned DiagNo = HasBareClause
? diag::err_ompx_more_than_three_expr_not_allowed
: diag::err_omp_multi_expr_not_allowed;
if (!checkNumExprsInClause<OMPNumTeamsClause>(*this, Clauses,
ClauseMaxNumExprs, DiagNo))
return StmtError();

return OMPTargetTeamsDirective::Create(getASTContext(), StartLoc, EndLoc,
Clauses, AStmt);
}
Expand All @@ -13825,6 +13856,10 @@ StmtResult SemaOpenMP::ActOnOpenMPTargetTeamsDistributeDirective(
if (!AStmt)
return StmtError();

if (!checkNumExprsInClause<OMPNumTeamsClause>(
*this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed))
return StmtError();

CapturedStmt *CS =
setBranchProtectedScope(SemaRef, OMPD_target_teams_distribute, AStmt);

Expand All @@ -13851,6 +13886,10 @@ StmtResult SemaOpenMP::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
if (!AStmt)
return StmtError();

if (!checkNumExprsInClause<OMPNumTeamsClause>(
*this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed))
return StmtError();

CapturedStmt *CS = setBranchProtectedScope(
SemaRef, OMPD_target_teams_distribute_parallel_for, AStmt);

Expand Down Expand Up @@ -13878,6 +13917,10 @@ StmtResult SemaOpenMP::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
if (!AStmt)
return StmtError();

if (!checkNumExprsInClause<OMPNumTeamsClause>(
*this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed))
return StmtError();

CapturedStmt *CS = setBranchProtectedScope(
SemaRef, OMPD_target_teams_distribute_parallel_for_simd, AStmt);

Expand Down Expand Up @@ -13908,6 +13951,10 @@ StmtResult SemaOpenMP::ActOnOpenMPTargetTeamsDistributeSimdDirective(
if (!AStmt)
return StmtError();

if (!checkNumExprsInClause<OMPNumTeamsClause>(
*this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed))
return StmtError();

CapturedStmt *CS = setBranchProtectedScope(
SemaRef, OMPD_target_teams_distribute_simd, AStmt);

Expand Down Expand Up @@ -14955,9 +15002,6 @@ OMPClause *SemaOpenMP::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
case OMPC_ordered:
Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
break;
case OMPC_num_teams:
Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
break;
case OMPC_thread_limit:
Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
break;
Expand Down Expand Up @@ -15064,6 +15108,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
case OMPC_affinity:
case OMPC_when:
case OMPC_bind:
case OMPC_num_teams:
default:
llvm_unreachable("Clause is not allowed.");
}
Expand Down Expand Up @@ -16927,6 +16972,9 @@ OMPClause *SemaOpenMP::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
static_cast<OpenMPDoacrossClauseModifier>(ExtraModifier),
ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
break;
case OMPC_num_teams:
Res = ActOnOpenMPNumTeamsClause(VarList, StartLoc, LParenLoc, EndLoc);
break;
case OMPC_if:
case OMPC_depobj:
case OMPC_final:
Expand Down Expand Up @@ -16957,7 +17005,6 @@ OMPClause *SemaOpenMP::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
case OMPC_device:
case OMPC_threads:
case OMPC_simd:
case OMPC_num_teams:
case OMPC_thread_limit:
case OMPC_priority:
case OMPC_grainsize:
Expand Down Expand Up @@ -17885,7 +17932,8 @@ buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
return UnresolvedLookupExpr::Create(
SemaRef.Context, /*NamingClass=*/nullptr,
ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
/*ADL=*/true, ResSet.begin(), ResSet.end(), /*KnownDependent=*/false);
/*ADL=*/true, ResSet.begin(), ResSet.end(), /*KnownDependent=*/false,
/*KnownInstantiationDependent=*/false);
}
// Lookup inside the classes.
// C++ [over.match.oper]p3:
Expand Down Expand Up @@ -20751,7 +20799,8 @@ static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
return UnresolvedLookupExpr::Create(
SemaRef.Context, /*NamingClass=*/nullptr,
MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
/*ADL=*/false, URS.begin(), URS.end(), /*KnownDependent=*/false);
/*ADL=*/false, URS.begin(), URS.end(), /*KnownDependent=*/false,
/*KnownInstantiationDependent=*/false);
}
SourceLocation Loc = MapperId.getLoc();
// [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
Expand Down Expand Up @@ -21834,32 +21883,40 @@ const ValueDecl *SemaOpenMP::getOpenMPDeclareMapperVarName() const {
return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl();
}

OMPClause *SemaOpenMP::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
OMPClause *SemaOpenMP::ActOnOpenMPNumTeamsClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc) {
Expr *ValExpr = NumTeams;
Stmt *HelperValStmt = nullptr;

// OpenMP [teams Constrcut, Restrictions]
// The num_teams expression must evaluate to a positive integer value.
if (!isNonNegativeIntegerValue(ValExpr, SemaRef, OMPC_num_teams,
/*StrictlyPositive=*/true))
if (VarList.empty())
return nullptr;

for (Expr *ValExpr : VarList) {
// OpenMP [teams Constrcut, Restrictions]
// The num_teams expression must evaluate to a positive integer value.
if (!isNonNegativeIntegerValue(ValExpr, SemaRef, OMPC_num_teams,
/*StrictlyPositive=*/true))
return nullptr;
}

OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
DKind, OMPC_num_teams, getLangOpts().OpenMP);
if (CaptureRegion != OMPD_unknown &&
!SemaRef.CurContext->isDependentContext()) {
if (CaptureRegion == OMPD_unknown || SemaRef.CurContext->isDependentContext())
return OMPNumTeamsClause::Create(getASTContext(), CaptureRegion, StartLoc,
LParenLoc, EndLoc, VarList,
/*PreInit=*/nullptr);

llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
SmallVector<Expr *, 3> Vars;
for (Expr *ValExpr : VarList) {
ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
HelperValStmt = buildPreInits(getASTContext(), Captures);
Vars.push_back(ValExpr);
}

return new (getASTContext()) OMPNumTeamsClause(
ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
Stmt *PreInit = buildPreInits(getASTContext(), Captures);
return OMPNumTeamsClause::Create(getASTContext(), CaptureRegion, StartLoc,
LParenLoc, EndLoc, Vars, PreInit);
}

OMPClause *SemaOpenMP::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Sema/SemaOverload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14093,9 +14093,9 @@ ExprResult Sema::CreateUnresolvedLookupExpr(CXXRecordDecl *NamingClass,
DeclarationNameInfo DNI,
const UnresolvedSetImpl &Fns,
bool PerformADL) {
return UnresolvedLookupExpr::Create(Context, NamingClass, NNSLoc, DNI,
PerformADL, Fns.begin(), Fns.end(),
/*KnownDependent=*/false);
return UnresolvedLookupExpr::Create(
Context, NamingClass, NNSLoc, DNI, PerformADL, Fns.begin(), Fns.end(),
/*KnownDependent=*/false, /*KnownInstantiationDependent=*/false);
}

ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl,
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Sema/SemaPPC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ static bool isPPC_64Builtin(unsigned BuiltinID) {
case PPC::BI__builtin_bpermd:
case PPC::BI__builtin_pdepd:
case PPC::BI__builtin_pextd:
case PPC::BI__builtin_ppc_cdtbcd:
case PPC::BI__builtin_ppc_cbcdtd:
case PPC::BI__builtin_ppc_addg6s:
case PPC::BI__builtin_ppc_ldarx:
case PPC::BI__builtin_ppc_stdcx:
case PPC::BI__builtin_ppc_tdw:
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/Sema/SemaRISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ void RISCVIntrinsicManagerImpl::ConstructRVVIntrinsics(
{"zvksh", RVV_REQ_Zvksh},
{"zvfbfwma", RVV_REQ_Zvfbfwma},
{"zvfbfmin", RVV_REQ_Zvfbfmin},
{"zvfh", RVV_REQ_Zvfh},
{"experimental", RVV_REQ_Experimental}};

// Construction of RVVIntrinsicRecords need to sync with createRVVIntrinsics
Expand Down Expand Up @@ -280,6 +281,11 @@ void RISCVIntrinsicManagerImpl::ConstructRVVIntrinsics(
if ((BaseTypeI & Record.TypeRangeMask) != BaseTypeI)
continue;

// TODO: Remove the check below and use RequiredFeatures in
// riscv_vector.td to check the intrinsics instead, the type check should
// be done in checkRVVTypeSupport. This check also not able to work on the
// intrinsics that have Float16 but the BaseType is not Float16 such as
// `vfcvt_f_x_v`.
if (BaseType == BasicType::Float16) {
if ((Record.RequiredExtensions & RVV_REQ_Zvfhmin) == RVV_REQ_Zvfhmin) {
if (!TI.hasFeature("zvfhmin"))
Expand Down
76 changes: 53 additions & 23 deletions clang/lib/Sema/SemaTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4436,7 +4436,8 @@ ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
UnresolvedLookupExpr *ULE = UnresolvedLookupExpr::Create(
Context, R.getNamingClass(), SS.getWithLocInContext(Context),
TemplateKWLoc, R.getLookupNameInfo(), RequiresADL, TemplateArgs,
R.begin(), R.end(), KnownDependent);
R.begin(), R.end(), KnownDependent,
/*KnownInstantiationDependent=*/false);

// Model the templates with UnresolvedTemplateTy. The expression should then
// either be transformed in an instantiation or be diagnosed in
Expand Down Expand Up @@ -9051,7 +9052,8 @@ bool Sema::CheckFunctionTemplateSpecialization(

bool
Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
assert(!isa<TemplateDecl>(Member) && "Only for non-template members");
assert(!Member->isTemplateDecl() && !Member->getDescribedTemplate() &&
"Only for non-template members");

// Try to find the member we are instantiating.
NamedDecl *FoundInstantiation = nullptr;
Expand All @@ -9062,51 +9064,79 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
if (Previous.empty()) {
// Nowhere to look anyway.
} else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Member)) {
SmallVector<FunctionDecl *> Candidates;
bool Ambiguous = false;
for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
I != E; ++I) {
CXXMethodDecl *Method =
dyn_cast<CXXMethodDecl>((*I)->getUnderlyingDecl());
UnresolvedSet<8> Candidates;
for (NamedDecl *Candidate : Previous) {
auto *Method = dyn_cast<CXXMethodDecl>(Candidate->getUnderlyingDecl());
// Ignore any candidates that aren't member functions.
if (!Method)
continue;

QualType Adjusted = Function->getType();
if (!hasExplicitCallingConv(Adjusted))
Adjusted = adjustCCAndNoReturn(Adjusted, Method->getType());
// Ignore any candidates with the wrong type.
// This doesn't handle deduced return types, but both function
// declarations should be undeduced at this point.
// FIXME: The exception specification should probably be ignored when
// comparing the types.
if (!Context.hasSameType(Adjusted, Method->getType()))
continue;

// Ignore any candidates with unsatisfied constraints.
if (ConstraintSatisfaction Satisfaction;
Method->getTrailingRequiresClause() &&
(CheckFunctionConstraints(Method, Satisfaction,
/*UsageLoc=*/Member->getLocation(),
/*ForOverloadResolution=*/true) ||
!Satisfaction.IsSatisfied))
continue;
Candidates.push_back(Method);
FunctionDecl *MoreConstrained =
Instantiation ? getMoreConstrainedFunction(
Method, cast<FunctionDecl>(Instantiation))
: Method;
if (!MoreConstrained) {
Ambiguous = true;
continue;

Candidates.addDecl(Candidate);
}

// If we have no viable candidates left after filtering, we are done.
if (Candidates.empty())
return false;

// Find the function that is more constrained than every other function it
// has been compared to.
UnresolvedSetIterator Best = Candidates.begin();
CXXMethodDecl *BestMethod = nullptr;
for (UnresolvedSetIterator I = Candidates.begin(), E = Candidates.end();
I != E; ++I) {
auto *Method = cast<CXXMethodDecl>(I->getUnderlyingDecl());
if (I == Best ||
getMoreConstrainedFunction(Method, BestMethod) == Method) {
Best = I;
BestMethod = Method;
}
if (MoreConstrained == Method) {
Ambiguous = false;
FoundInstantiation = *I;
Instantiation = Method;
InstantiatedFrom = Method->getInstantiatedFromMemberFunction();
MSInfo = Method->getMemberSpecializationInfo();
}

FoundInstantiation = *Best;
Instantiation = BestMethod;
InstantiatedFrom = BestMethod->getInstantiatedFromMemberFunction();
MSInfo = BestMethod->getMemberSpecializationInfo();

// Make sure the best candidate is more constrained than all of the others.
bool Ambiguous = false;
for (UnresolvedSetIterator I = Candidates.begin(), E = Candidates.end();
I != E; ++I) {
auto *Method = cast<CXXMethodDecl>(I->getUnderlyingDecl());
if (I != Best &&
getMoreConstrainedFunction(Method, BestMethod) != BestMethod) {
Ambiguous = true;
break;
}
}

if (Ambiguous) {
Diag(Member->getLocation(), diag::err_function_member_spec_ambiguous)
<< Member << (InstantiatedFrom ? InstantiatedFrom : Instantiation);
for (FunctionDecl *Candidate : Candidates)
for (NamedDecl *Candidate : Candidates) {
Candidate = Candidate->getUnderlyingDecl();
Diag(Candidate->getLocation(), diag::note_function_member_spec_matched)
<< Candidate;
}
return true;
}
} else if (isa<VarDecl>(Member)) {
Expand Down
20 changes: 9 additions & 11 deletions clang/lib/Sema/SemaTemplateInstantiate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/TimeProfiler.h"
#include <optional>

Expand Down Expand Up @@ -1657,11 +1658,12 @@ namespace {
LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
Sema::ConstraintEvalRAII<TemplateInstantiator> RAII(*this);

ExprResult Result = inherited::TransformLambdaExpr(E);
if (Result.isInvalid())
return Result;
return inherited::TransformLambdaExpr(E);
}

CXXMethodDecl *MD = Result.getAs<LambdaExpr>()->getCallOperator();
ExprResult RebuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
LambdaScopeInfo *LSI) {
CXXMethodDecl *MD = LSI->CallOperator;
for (ParmVarDecl *PVD : MD->parameters()) {
assert(PVD && "null in a parameter list");
if (!PVD->hasDefaultArg())
Expand All @@ -1680,8 +1682,7 @@ namespace {
PVD->setDefaultArg(ErrorResult.get());
}
}

return Result;
return inherited::RebuildLambdaExpr(StartLoc, EndLoc, LSI);
}

StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body) {
Expand All @@ -1694,11 +1695,8 @@ namespace {
// `true` to temporarily fix this issue.
// FIXME: This temporary fix can be removed after fully implementing
// p0588r1.
bool Prev = EvaluateConstraints;
EvaluateConstraints = true;
StmtResult Stmt = inherited::TransformLambdaBody(E, Body);
EvaluateConstraints = Prev;
return Stmt;
llvm::SaveAndRestore _(EvaluateConstraints, true);
return inherited::TransformLambdaBody(E, Body);
}

ExprResult TransformRequiresExpr(RequiresExpr *E) {
Expand Down
16 changes: 16 additions & 0 deletions clang/lib/Sema/SemaX86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ bool SemaX86::CheckBuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall) {
case X86::BI__builtin_ia32_vgetexppd256_round_mask:
case X86::BI__builtin_ia32_vgetexpps256_round_mask:
case X86::BI__builtin_ia32_vgetexpph256_round_mask:
case X86::BI__builtin_ia32_vcvttph2ibs256_mask:
case X86::BI__builtin_ia32_vcvttph2iubs256_mask:
case X86::BI__builtin_ia32_vcvttps2ibs256_mask:
case X86::BI__builtin_ia32_vcvttps2iubs256_mask:
case X86::BI__builtin_ia32_vcvttph2ibs512_mask:
case X86::BI__builtin_ia32_vcvttph2iubs512_mask:
case X86::BI__builtin_ia32_vcvttps2ibs512_mask:
case X86::BI__builtin_ia32_vcvttps2iubs512_mask:
ArgNum = 3;
break;
case X86::BI__builtin_ia32_cmppd512_mask:
Expand Down Expand Up @@ -302,6 +310,14 @@ bool SemaX86::CheckBuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall) {
case X86::BI__builtin_ia32_vcvtph2uqq256_round_mask:
case X86::BI__builtin_ia32_vcvtqq2ph256_round_mask:
case X86::BI__builtin_ia32_vcvtuqq2ph256_round_mask:
case X86::BI__builtin_ia32_vcvtph2ibs256_mask:
case X86::BI__builtin_ia32_vcvtph2iubs256_mask:
case X86::BI__builtin_ia32_vcvtps2ibs256_mask:
case X86::BI__builtin_ia32_vcvtps2iubs256_mask:
case X86::BI__builtin_ia32_vcvtph2ibs512_mask:
case X86::BI__builtin_ia32_vcvtph2iubs512_mask:
case X86::BI__builtin_ia32_vcvtps2ibs512_mask:
case X86::BI__builtin_ia32_vcvtps2iubs512_mask:
ArgNum = 3;
HasRC = true;
break;
Expand Down
70 changes: 55 additions & 15 deletions clang/lib/Sema/TreeTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -2079,10 +2079,11 @@ class TreeTransform {
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
OMPClause *RebuildOMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc,
OMPClause *RebuildOMPNumTeamsClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc) {
return getSema().OpenMP().ActOnOpenMPNumTeamsClause(NumTeams, StartLoc,
return getSema().OpenMP().ActOnOpenMPNumTeamsClause(VarList, StartLoc,
LParenLoc, EndLoc);
}

Expand Down Expand Up @@ -4028,6 +4029,20 @@ class TreeTransform {
NumExpansions);
}

ExprResult RebuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
LambdaScopeInfo *LSI) {
for (ParmVarDecl *PVD : LSI->CallOperator->parameters()) {
if (Expr *Init = PVD->getInit())
LSI->ContainsUnexpandedParameterPack |=
Init->containsUnexpandedParameterPack();
else if (PVD->hasUninstantiatedDefaultArg())
LSI->ContainsUnexpandedParameterPack |=
PVD->getUninstantiatedDefaultArg()
->containsUnexpandedParameterPack();
}
return getSema().BuildLambdaExpr(StartLoc, EndLoc, LSI);
}

/// Build an empty C++1z fold-expression with the given operator.
///
/// By default, produces the fallback value for the fold-expression, or
Expand Down Expand Up @@ -5825,7 +5840,8 @@ QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
const DependentAddressSpaceType *T = TL.getTypePtr();

QualType pointeeType = getDerived().TransformType(T->getPointeeType());
QualType pointeeType =
getDerived().TransformType(TLB, TL.getPointeeTypeLoc());

if (pointeeType.isNull())
return QualType();
Expand Down Expand Up @@ -5858,9 +5874,7 @@ QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
NewTL.setAttrNameLoc(TL.getAttrNameLoc());

} else {
TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(
Result, getDerived().getBaseLocation());
TransformType(TLB, DI->getTypeLoc());
TLB.TypeWasModifiedSafely(Result);
}

return Result;
Expand Down Expand Up @@ -8284,6 +8298,7 @@ StmtResult
TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
bool DeclChanged = false;
SmallVector<Decl *, 4> Decls;
LambdaScopeInfo *LSI = getSema().getCurLambda();
for (auto *D : S->decls()) {
Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
if (!Transformed)
Expand All @@ -8292,6 +8307,15 @@ TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
if (Transformed != D)
DeclChanged = true;

if (LSI && isa<TypeDecl>(Transformed))
LSI->ContainsUnexpandedParameterPack |=
getSema()
.getASTContext()
.getTypeDeclType(cast<TypeDecl>(Transformed))
.getCanonicalType()
.getTypePtr()
->containsUnexpandedParameterPack();

Decls.push_back(Transformed);
}

Expand Down Expand Up @@ -10662,7 +10686,7 @@ TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
SemaRef.Context, /*NamingClass=*/nullptr,
ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
/*ADL=*/true, Decls.begin(), Decls.end(),
/*KnownDependent=*/false));
/*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
} else
UnresolvedReductions.push_back(nullptr);
}
Expand Down Expand Up @@ -10709,7 +10733,7 @@ OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
SemaRef.Context, /*NamingClass=*/nullptr,
ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
/*ADL=*/true, Decls.begin(), Decls.end(),
/*KnownDependent=*/false));
/*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
} else
UnresolvedReductions.push_back(nullptr);
}
Expand Down Expand Up @@ -10755,7 +10779,7 @@ TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
SemaRef.Context, /*NamingClass=*/nullptr,
ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
/*ADL=*/true, Decls.begin(), Decls.end(),
/*KnownDependent=*/false));
/*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
} else
UnresolvedReductions.push_back(nullptr);
}
Expand Down Expand Up @@ -10937,7 +10961,7 @@ bool transformOMPMappableExprListClause(
TT.getSema().Context, /*NamingClass=*/nullptr,
MapperIdScopeSpec.getWithLocInContext(TT.getSema().Context),
MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),
/*KnownDependent=*/false));
/*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
} else {
UnresolvedMappers.push_back(nullptr);
}
Expand Down Expand Up @@ -10994,7 +11018,7 @@ TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
template <typename Derived>
OMPClause *
TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
ExprResult E = getDerived().TransformExpr(C->getNumTeams());
ExprResult E = getDerived().TransformExpr(C->getNumTeams().front());
if (E.isInvalid())
return nullptr;
return getDerived().RebuildOMPNumTeamsClause(
Expand Down Expand Up @@ -14523,7 +14547,6 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {

CXXMethodDecl *NewCallOperator =
getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
NewCallOperator->setLexicalDeclContext(getSema().CurContext);

// Enter the scope of the lambda.
getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
Expand Down Expand Up @@ -14591,6 +14614,13 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
}
NewVDs.push_back(NewVD);
getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
// Cases we want to tackle:
// ([C(Pack)] {}, ...)
// But rule out cases e.g.
// [...C = Pack()] {}
if (NewC.EllipsisLoc.isInvalid())
LSI->ContainsUnexpandedParameterPack |=
Init.get()->containsUnexpandedParameterPack();
}

if (Invalid)
Expand Down Expand Up @@ -14658,6 +14688,11 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
continue;
}

// This is not an init-capture; however it contains an unexpanded pack e.g.
// ([Pack] {}(), ...)
if (auto *VD = dyn_cast<VarDecl>(CapturedVar); VD && !C->isPackExpansion())
LSI->ContainsUnexpandedParameterPack |= VD->isParameterPack();

// Capture the transformed variable.
getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
EllipsisLoc);
Expand All @@ -14669,9 +14704,12 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
auto TPL = getDerived().TransformTemplateParameterList(
E->getTemplateParameterList());
LSI->GLTemplateParameterList = TPL;
if (TPL)
if (TPL) {
getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
TPL);
LSI->ContainsUnexpandedParameterPack |=
TPL->containsUnexpandedParameterPack();
}

// Transform the type of the original lambda's call operator.
// The transformation MUST be done in the CurrentInstantiationScope since
Expand Down Expand Up @@ -14710,6 +14748,8 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {

if (NewCallOpType.isNull())
return ExprError();
LSI->ContainsUnexpandedParameterPack |=
NewCallOpType->containsUnexpandedParameterPack();
NewCallOpTSI =
NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, NewCallOpType);
}
Expand Down Expand Up @@ -14824,8 +14864,8 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
Class->setTypeForDecl(nullptr);
getSema().Context.getTypeDeclType(Class);

return getSema().BuildLambdaExpr(E->getBeginLoc(), Body.get()->getEndLoc(),
&LSICopy);
return getDerived().RebuildLambdaExpr(E->getBeginLoc(),
Body.get()->getEndLoc(), &LSICopy);
}

template<typename Derived>
Expand Down
12 changes: 10 additions & 2 deletions clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/Sequence.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
Expand Down Expand Up @@ -10596,7 +10597,7 @@ OMPClause *OMPClauseReader::readClause() {
break;
}
case llvm::omp::OMPC_num_teams:
C = new (Context) OMPNumTeamsClause();
C = OMPNumTeamsClause::CreateEmpty(Context, Record.readInt());
break;
case llvm::omp::OMPC_thread_limit:
C = new (Context) OMPThreadLimitClause();
Expand Down Expand Up @@ -11418,8 +11419,15 @@ void OMPClauseReader::VisitOMPAllocateClause(OMPAllocateClause *C) {

void OMPClauseReader::VisitOMPNumTeamsClause(OMPNumTeamsClause *C) {
VisitOMPClauseWithPreInit(C);
C->setNumTeams(Record.readSubExpr());
C->setLParenLoc(Record.readSourceLocation());
unsigned NumVars = C->varlist_size();
SmallVector<Expr *, 16> Vars;
Vars.reserve(NumVars);
for ([[maybe_unused]] auto _ : llvm::seq<unsigned>(NumVars)) {
(void)_;
Vars.push_back(Record.readSubExpr());
}
C->setVarRefs(Vars);
}

void OMPClauseReader::VisitOMPThreadLimitClause(OMPThreadLimitClause *C) {
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/Serialization/ASTWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7556,9 +7556,11 @@ void OMPClauseWriter::VisitOMPAllocateClause(OMPAllocateClause *C) {
}

void OMPClauseWriter::VisitOMPNumTeamsClause(OMPNumTeamsClause *C) {
Record.push_back(C->varlist_size());
VisitOMPClauseWithPreInit(C);
Record.AddStmt(C->getNumTeams());
Record.AddSourceLocation(C->getLParenLoc());
for (auto *VE : C->varlist())
Record.AddStmt(VE);
}

void OMPClauseWriter::VisitOMPThreadLimitClause(OMPThreadLimitClause *C) {
Expand Down
2 changes: 1 addition & 1 deletion clang/test/AST/Interp/arrays.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ static_assert(*(&arr[0]) == 1, "");
static_assert(*(&arr[1]) == 2, "");

constexpr const int *OOB = (arr + 3) - 3; // both-error {{must be initialized by a constant expression}} \
// both-note {{cannot refer to element 3 of array of 2}}
// both-note {{cannot refer to element 3 of array of 2 elements}}

template<typename T>
constexpr T getElementOf(T* array, int i) {
Expand Down
26 changes: 13 additions & 13 deletions clang/test/AST/Interp/builtin-functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -866,11 +866,11 @@ namespace convertvector {
constexpr vector8BitInt128 from_vector8BitInt128_to_vector8BitInt128_var =
__builtin_convertvector((vector8BitInt128){0, 1, 2, 3, 4, 5, 6, 7},
vector8BitInt128);
static_assert(from_vector8BitInt128_to_vector8BitInt128_var[0] == 0, ""); // ref-error {{not an integral constant expression}}
static_assert(from_vector8BitInt128_to_vector8BitInt128_var[1] == 1, ""); // ref-error {{not an integral constant expression}}
static_assert(from_vector8BitInt128_to_vector8BitInt128_var[2] == 2, ""); // ref-error {{not an integral constant expression}}
static_assert(from_vector8BitInt128_to_vector8BitInt128_var[3] == 3, ""); // ref-error {{not an integral constant expression}}
static_assert(from_vector8BitInt128_to_vector8BitInt128_var[4] == 4, ""); // ref-error {{not an integral constant expression}}
static_assert(from_vector8BitInt128_to_vector8BitInt128_var[0] == 0, "");
static_assert(from_vector8BitInt128_to_vector8BitInt128_var[1] == 1, "");
static_assert(from_vector8BitInt128_to_vector8BitInt128_var[2] == 2, "");
static_assert(from_vector8BitInt128_to_vector8BitInt128_var[3] == 3, "");
static_assert(from_vector8BitInt128_to_vector8BitInt128_var[4] == 4, "");
}

namespace shufflevector {
Expand All @@ -890,14 +890,14 @@ namespace shufflevector {
constexpr vector8char vectorShuffle6 = __builtin_shufflevector(
vector4charConst1, vector4charConst2, 0, 2, 4, 6, 1, 3, 5, 7);

static_assert(vectorShuffle6[0] == 0, "");// ref-error {{not an integral constant expression}}
static_assert(vectorShuffle6[1] == 2, "");// ref-error {{not an integral constant expression}}
static_assert(vectorShuffle6[2] == 4, "");// ref-error {{not an integral constant expression}}
static_assert(vectorShuffle6[3] == 6, "");// ref-error {{not an integral constant expression}}
static_assert(vectorShuffle6[4] == 1, "");// ref-error {{not an integral constant expression}}
static_assert(vectorShuffle6[5] == 3, "");// ref-error {{not an integral constant expression}}
static_assert(vectorShuffle6[6] == 5, "");// ref-error {{not an integral constant expression}}
static_assert(vectorShuffle6[7] == 7, "");// ref-error {{not an integral constant expression}}
static_assert(vectorShuffle6[0] == 0, "");
static_assert(vectorShuffle6[1] == 2, "");
static_assert(vectorShuffle6[2] == 4, "");
static_assert(vectorShuffle6[3] == 6, "");
static_assert(vectorShuffle6[4] == 1, "");
static_assert(vectorShuffle6[5] == 3, "");
static_assert(vectorShuffle6[6] == 5, "");
static_assert(vectorShuffle6[7] == 7, "");

constexpr vector4char vectorShuffleFail1 = __builtin_shufflevector( // both-error {{must be initialized by a constant expression}}\
// ref-error {{index for __builtin_shufflevector not within the bounds of the input vectors; index of -1 found at position 0 is not permitted in a constexpr context}}
Expand Down
7 changes: 1 addition & 6 deletions clang/test/AST/Interp/c.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,6 @@ int somefunc(int i) {
// all-warning {{overflow in expression; result is 131'073 with type 'int'}}
}

/// FIXME: The following test is incorrect in the new interpreter.
/// The null pointer returns 16 from its getIntegerRepresentation().
#pragma clang diagnostic ignored "-Wpointer-to-int-cast"
struct ArrayStruct {
char n[1];
Expand All @@ -111,10 +109,7 @@ char name2[(int)&((struct ArrayStruct*)0)->n]; // expected-warning {{folded to c
// pedantic-expected-warning {{folded to constant array}} \
// ref-warning {{folded to constant array}} \
// pedantic-ref-warning {{folded to constant array}}
_Static_assert(sizeof(name2) == 0, ""); // expected-error {{failed}} \
// expected-note {{evaluates to}} \
// pedantic-expected-error {{failed}} \
// pedantic-expected-note {{evaluates to}}
_Static_assert(sizeof(name2) == 0, "");

#ifdef __SIZEOF_INT128__
void *PR28739d = &(&PR28739d)[(__int128)(unsigned long)-1]; // all-warning {{refers past the last possible element}}
Expand Down
17 changes: 17 additions & 0 deletions clang/test/AST/Interp/cxx20.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -841,3 +841,20 @@ namespace VariadicCallOperator {
}
constexpr int A = foo();
}

namespace DefinitionLoc {

struct NonConstexprCopy {
constexpr NonConstexprCopy() = default;
NonConstexprCopy(const NonConstexprCopy &);
constexpr NonConstexprCopy(NonConstexprCopy &&) = default;

int n = 42;
};

NonConstexprCopy::NonConstexprCopy(const NonConstexprCopy &) = default; // both-note {{here}}

constexpr NonConstexprCopy ncc1 = NonConstexprCopy(NonConstexprCopy());
constexpr NonConstexprCopy ncc2 = ncc1; // both-error {{constant expression}} \
// both-note {{non-constexpr constructor}}
}
25 changes: 25 additions & 0 deletions clang/test/AST/Interp/objc.mm
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,28 @@ @interface NSString
@end
constexpr NSString *t0 = @"abc";
constexpr NSString *t1 = @("abc");


#if __LP64__
typedef unsigned long NSUInteger;
typedef long NSInteger;
#else
typedef unsigned int NSUInteger;
typedef int NSInteger;
#endif


@class NSNumber;


@interface NSObject
+ (NSObject*)nsobject;
@end

@interface NSNumber : NSObject
+ (NSNumber *)numberWithInt:(int)value;
@end

int main(void) {
NSNumber *bv = @(1391126400 * 1000); // both-warning {{overflow in expression; result is -443'003'904 with type 'int'}}
}
60 changes: 35 additions & 25 deletions clang/test/AST/Interp/vectors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,39 @@

typedef int __attribute__((vector_size(16))) VI4;
constexpr VI4 A = {1,2,3,4};
static_assert(A[0] == 1, ""); // ref-error {{not an integral constant expression}}
static_assert(A[1] == 2, ""); // ref-error {{not an integral constant expression}}
static_assert(A[2] == 3, ""); // ref-error {{not an integral constant expression}}
static_assert(A[3] == 4, ""); // ref-error {{not an integral constant expression}}
static_assert(A[0] == 1, "");
static_assert(A[1] == 2, "");
static_assert(A[2] == 3, "");
static_assert(A[3] == 4, "");


/// FIXME: It would be nice if the note said 'vector' instead of 'array'.
static_assert(A[12] == 4, ""); // ref-error {{not an integral constant expression}} \
// expected-error {{not an integral constant expression}} \
// expected-note {{cannot refer to element 12 of array of 4 elements in a constant expression}}
static_assert(A[12] == 4, ""); // both-error {{not an integral constant expression}} \
// both-note {{cannot refer to element 12 of array of 4 elements in a constant expression}}


/// VectorSplat casts
typedef __attribute__(( ext_vector_type(4) )) float float4;
constexpr float4 vec4_0 = (float4)0.5f;
static_assert(vec4_0[0] == 0.5, ""); // ref-error {{not an integral constant expression}}
static_assert(vec4_0[1] == 0.5, ""); // ref-error {{not an integral constant expression}}
static_assert(vec4_0[2] == 0.5, ""); // ref-error {{not an integral constant expression}}
static_assert(vec4_0[3] == 0.5, ""); // ref-error {{not an integral constant expression}}
static_assert(vec4_0[0] == 0.5, "");
static_assert(vec4_0[1] == 0.5, "");
static_assert(vec4_0[2] == 0.5, "");
static_assert(vec4_0[3] == 0.5, "");
constexpr int vec4_0_discarded = ((float4)12.0f, 0);


/// ImplicitValueInitExpr of vector type
constexpr float4 arr4[2] = {
{1,2,3,4},
};
static_assert(arr4[0][0] == 1, ""); // ref-error {{not an integral constant expression}}
static_assert(arr4[0][1] == 2, ""); // ref-error {{not an integral constant expression}}
static_assert(arr4[0][2] == 3, ""); // ref-error {{not an integral constant expression}}
static_assert(arr4[0][3] == 4, ""); // ref-error {{not an integral constant expression}}
static_assert(arr4[1][0] == 0, ""); // ref-error {{not an integral constant expression}}
static_assert(arr4[1][0] == 0, ""); // ref-error {{not an integral constant expression}}
static_assert(arr4[1][0] == 0, ""); // ref-error {{not an integral constant expression}}
static_assert(arr4[1][0] == 0, ""); // ref-error {{not an integral constant expression}}
static_assert(arr4[0][0] == 1, "");
static_assert(arr4[0][1] == 2, "");
static_assert(arr4[0][2] == 3, "");
static_assert(arr4[0][3] == 4, "");
static_assert(arr4[1][0] == 0, "");
static_assert(arr4[1][0] == 0, "");
static_assert(arr4[1][0] == 0, "");
static_assert(arr4[1][0] == 0, "");


/// From constant-expression-cxx11.cpp
Expand Down Expand Up @@ -65,10 +64,10 @@ namespace {
namespace BoolToSignedIntegralCast{
typedef __attribute__((__ext_vector_type__(4))) unsigned int int4;
constexpr int4 intsT = (int4)true;
static_assert(intsT[0] == -1, "");// ref-error {{not an integral constant expression}}
static_assert(intsT[1] == -1, "");// ref-error {{not an integral constant expression}}
static_assert(intsT[2] == -1, "");// ref-error {{not an integral constant expression}}
static_assert(intsT[3] == -1, "");// ref-error {{not an integral constant expression}}
static_assert(intsT[0] == -1, "");
static_assert(intsT[1] == -1, "");
static_assert(intsT[2] == -1, "");
static_assert(intsT[3] == -1, "");
}

namespace VectorElementExpr {
Expand All @@ -78,8 +77,8 @@ namespace VectorElementExpr {
static_assert(oneElt == 3);

constexpr int2 twoElts = ((int4){11, 22, 33, 44}).yz;
static_assert(twoElts.x == 22, ""); // ref-error {{not an integral constant expression}}
static_assert(twoElts.y == 33, ""); // ref-error {{not an integral constant expression}}
static_assert(twoElts.x == 22, "");
static_assert(twoElts.y == 33, "");
}

namespace Temporaries {
Expand All @@ -91,3 +90,14 @@ namespace Temporaries {
};
int &&s = S().w[1];
}

#ifdef __SIZEOF_INT128__
namespace bigint {
typedef __attribute__((__ext_vector_type__(4))) __int128 bigint4;
constexpr bigint4 A = (bigint4)true;
static_assert(A[0] == -1, "");
static_assert(A[1] == -1, "");
static_assert(A[2] == -1, "");
static_assert(A[3] == -1, "");
}
#endif
116 changes: 73 additions & 43 deletions clang/test/CXX/temp/temp.spec/temp.expl.spec/p14-23.cpp
Original file line number Diff line number Diff line change
@@ -1,60 +1,90 @@
// RUN: %clang_cc1 -std=c++20 -verify %s

template<int I>
concept C = I >= 4;
namespace N0 {
template<int I>
concept C = I >= 4;

template<int I>
concept D = I < 8;
template<int I>
concept D = I < 8;

template<int I>
struct A {
constexpr static int f() { return 0; }
constexpr static int f() requires C<I> && D<I> { return 1; }
constexpr static int f() requires C<I> { return 2; }
template<int I>
struct A {
constexpr static int f() { return 0; }
constexpr static int f() requires C<I> && D<I> { return 1; }
constexpr static int f() requires C<I> { return 2; }

constexpr static int g() requires C<I> { return 0; } // #candidate-0
constexpr static int g() requires D<I> { return 1; } // #candidate-1
constexpr static int g() requires C<I> { return 0; } // #candidate-0
constexpr static int g() requires D<I> { return 1; } // #candidate-1

constexpr static int h() requires C<I> { return 0; } // expected-note {{member declaration nearly matches}}
};
constexpr static int h() requires C<I> { return 0; } // expected-note {{member declaration nearly matches}}
};

template<>
constexpr int A<2>::f() { return 3; }
template<>
constexpr int A<2>::f() { return 3; }

template<>
constexpr int A<4>::f() { return 4; }
template<>
constexpr int A<4>::f() { return 4; }

template<>
constexpr int A<8>::f() { return 5; }
template<>
constexpr int A<8>::f() { return 5; }

static_assert(A<3>::f() == 0);
static_assert(A<5>::f() == 1);
static_assert(A<9>::f() == 2);
static_assert(A<2>::f() == 3);
static_assert(A<4>::f() == 4);
static_assert(A<8>::f() == 5);
static_assert(A<3>::f() == 0);
static_assert(A<5>::f() == 1);
static_assert(A<9>::f() == 2);
static_assert(A<2>::f() == 3);
static_assert(A<4>::f() == 4);
static_assert(A<8>::f() == 5);

template<>
constexpr int A<0>::g() { return 2; }
template<>
constexpr int A<0>::g() { return 2; }

template<>
constexpr int A<8>::g() { return 3; }
template<>
constexpr int A<8>::g() { return 3; }

template<>
constexpr int A<6>::g() { return 4; } // expected-error {{ambiguous member function specialization 'A<6>::g' of 'A::g'}}
// expected-note@#candidate-0 {{member function specialization matches 'g'}}
// expected-note@#candidate-1 {{member function specialization matches 'g'}}
template<>
constexpr int A<6>::g() { return 4; } // expected-error {{ambiguous member function specialization 'N0::A<6>::g' of 'N0::A::g'}}
// expected-note@#candidate-0 {{member function specialization matches 'g'}}
// expected-note@#candidate-1 {{member function specialization matches 'g'}}

static_assert(A<9>::g() == 0);
static_assert(A<1>::g() == 1);
static_assert(A<0>::g() == 2);
static_assert(A<8>::g() == 3);
static_assert(A<9>::g() == 0);
static_assert(A<1>::g() == 1);
static_assert(A<0>::g() == 2);
static_assert(A<8>::g() == 3);

template<>
constexpr int A<4>::h() { return 1; }
template<>
constexpr int A<4>::h() { return 1; }

template<>
constexpr int A<0>::h() { return 2; } // expected-error {{out-of-line definition of 'h' does not match any declaration in 'A<0>'}}
template<>
constexpr int A<0>::h() { return 2; } // expected-error {{out-of-line definition of 'h' does not match any declaration in 'N0::A<0>'}}

static_assert(A<5>::h() == 0);
static_assert(A<4>::h() == 1);
static_assert(A<5>::h() == 0);
static_assert(A<4>::h() == 1);
} // namespace N0

namespace N1 {
template<int I>
concept C = I > 0;

template<int I>
concept D = I > 1;

template<int I>
concept E = I > 2;

template<int I>
struct A {
void f() requires C<I> && D<I>; // expected-note {{member function specialization matches 'f'}}
void f() requires C<I> && E<I>; // expected-note {{member function specialization matches 'f'}}
void f() requires C<I> && D<I> && true; // expected-note {{member function specialization matches 'f'}}

void g() requires C<I> && E<I>; // expected-note {{member function specialization matches 'g'}}
void g() requires C<I> && D<I>; // expected-note {{member function specialization matches 'g'}}
void g() requires C<I> && D<I> && true; // expected-note {{member function specialization matches 'g'}}
};

template<>
void A<3>::f(); // expected-error {{ambiguous member function specialization 'N1::A<3>::f' of 'N1::A::f'}}

template<>
void A<3>::g(); // expected-error {{ambiguous member function specialization 'N1::A<3>::g' of 'N1::A::g'}}
} // namespace N1
58 changes: 58 additions & 0 deletions clang/test/CodeGen/PowerPC/builtins-bcd-assist.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
// REQUIRES: powerpc-registered-target
// RUN: %clang_cc1 -triple powerpc64le-unknown-linux -O2 -target-cpu pwr7 \
// RUN: -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -triple powerpc64-unknown-aix -O2 -target-cpu pwr7 \
// RUN: -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -triple powerpc-unknown-aix -O2 -target-cpu pwr7 \
// RUN: -emit-llvm %s -o - | FileCheck %s

// CHECK-LABEL: define{{.*}} i64 @cdtbcd_test(i64
// CHECK: [[CONV:%.*]] = trunc i64 {{.*}} to i32
// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ppc.cdtbcd(i32 [[CONV]])
// CHECK-NEXT: [[CONV1:%.*]] = zext i32 [[TMP0]] to i64
// CHECK-NEXT: ret i64 [[CONV1]]
long long cdtbcd_test(long long ll) {
return __builtin_cdtbcd (ll);
}

// CHECK-LABEL: define{{.*}} i32 @cdtbcd_test_ui(i32
// CHECK: [[TMP0:%.*]] = tail call i32 @llvm.ppc.cdtbcd(i32
// CHECK-NEXT: ret i32 [[TMP0]]
unsigned int cdtbcd_test_ui(unsigned int ui) {
return __builtin_cdtbcd (ui);
}

// CHECK-LABEL: define{{.*}} i64 @cbcdtd_test(i64
// CHECK: [[CONV:%.*]] = trunc i64 {{.*}} to i32
// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ppc.cbcdtd(i32 [[CONV]])
// CHECK-NEXT: [[CONV1:%.*]] = zext i32 [[TMP0]] to i64
// CHECK-NEXT: ret i64 [[CONV1]]
long long cbcdtd_test(long long ll) {
return __builtin_cbcdtd (ll);
}

// CHECK-LABEL: define{{.*}} i32 @cbcdtd_test_ui(i32
// CHECK: [[TMP0:%.*]] = tail call i32 @llvm.ppc.cbcdtd(i32
// CHECK-NEXT: ret i32 [[TMP0]]
unsigned int cbcdtd_test_ui(unsigned int ui) {
return __builtin_cbcdtd (ui);
}

// CHECK-LABEL: define{{.*}} i64 @addg6s_test(i64
// CHECK: [[CONV:%.*]] = trunc i64 {{.*}} to i32
// CHECK-NEXT: [[CONV1:%.*]] = trunc i64 {{.*}} to i32
// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ppc.addg6s(i32 [[CONV]], i32 [[CONV1]])
// CHECK-NEXT: [[CONV2:%.*]] = zext i32 [[TMP0]] to i64
// CHECK-NEXT: ret i64 [[CONV2]]
//
long long addg6s_test(long long ll, long long ll2) {
return __builtin_addg6s (ll, ll2);
}

// CHECK-LABEL: define{{.*}} i32 @addg6s_test_ui(i32
// CHECK: [[TMP0:%.*]] = tail call i32 @llvm.ppc.addg6s(i32 {{.*}}, i32
// CHECK-NEXT: ret i32 [[TMP0]]
unsigned int addg6s_test_ui(unsigned int ui, unsigned int ui2) {
return __builtin_addg6s (ui, ui2);
}
75 changes: 75 additions & 0 deletions clang/test/CodeGen/PowerPC/builtins-ppc-bcd-assist.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
// REQUIRES: powerpc-registered-target
// RUN: %clang_cc1 -triple powerpc64le-unknown-linux -O2 -target-cpu pwr7 \
// RUN: -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -triple powerpc64-unknown-aix -O2 -target-cpu pwr7 \
// RUN: -emit-llvm %s -o - | FileCheck %s
// RUN: not %clang_cc1 -triple powerpc-unknown-aix -O2 -target-cpu pwr7 \
// RUN: -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-32-ERROR

// CHECK-LABEL: define{{.*}} i64 @cdtbcd_test(i64
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ppc.cdtbcdd(i64
// CHECK-NEXT: ret i64 [[TMP0]]
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
// CHECK-32-ERROR: #define __cdtbcd __builtin_ppc_cdtbcd
long long cdtbcd_test(long long ll) {
return __cdtbcd (ll);
}

// CHECK-LABEL: define{{.*}} i32 @cdtbcd_test_ui(i32
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[CONV:%.*]] = zext i32 {{.*}} to i64
// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ppc.cdtbcdd(i64 [[CONV]])
// CHECK-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP0]] to i32
// CHECK-NEXT: ret i32 [[CONV1]]
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
// CHECK-32-ERROR: #define __cdtbcd __builtin_ppc_cdtbcd
unsigned int cdtbcd_test_ui(unsigned int ui) {
return __cdtbcd (ui);
}

// CHECK-LABEL: define{{.*}} i64 @cbcdtd_test(i64
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ppc.cbcdtdd(i64
// CHECK-NEXT: ret i64 [[TMP0]]
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
// CHECK-32-ERROR: #define __cbcdtd __builtin_ppc_cbcdtd
long long cbcdtd_test(long long ll) {
return __cbcdtd (ll);
}

// CHECK-LABEL: define{{.*}} i32 @cbcdtd_test_ui(i32
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[CONV:%.*]] = zext i32 {{.*}} to i64
// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ppc.cbcdtdd(i64 [[CONV]])
// CHECK-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP0]] to i32
// CHECK-NEXT: ret i32 [[CONV1]]
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
// CHECK-32-ERROR: #define __cbcdtd __builtin_ppc_cbcdtd
unsigned int cbcdtd_test_ui(unsigned int ui) {
return __cbcdtd (ui);
}

// CHECK-LABEL: define{{.*}} i64 @addg6s_test(i64
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ppc.addg6sd(i64 {{.*}}, i64 {{.*}})
// CHECK-NEXT: ret i64 [[TMP0]]
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
// CHECK-32-ERROR: #define __addg6s __builtin_ppc_addg6s
long long addg6s_test(long long ll, long long ll2) {
return __addg6s (ll, ll2);
}

// CHECK-LABEL: define{{.*}} i32 @addg6s_test_ui(i32
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[CONV:%.*]] = zext i32 {{.*}} to i64
// CHECK-NEXT: [[CONV1:%.*]] = zext i32 {{.*}} to i64
// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ppc.addg6sd(i64 {{.*}}, i64
// CHECK-NEXT: [[CONV2:%.*]] = trunc i64 [[TMP0]] to i32
// CHECK-NEXT: ret i32 [[CONV2]]
// CHECK-32-ERROR: error: this builtin is only available on 64-bit targets
// CHECK-32-ERROR: #define __addg6s __builtin_ppc_addg6s
unsigned int addg6s_test_ui(unsigned int ui, unsigned int ui2) {
return __addg6s (ui, ui2);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2
// REQUIRES: riscv-registered-target
// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \
// RUN: -target-feature +zvfh -disable-O0-optnone \
// RUN: -target-feature +zvfhmin -target-feature +zvfbfmin -disable-O0-optnone \
// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \
// RUN: FileCheck --check-prefix=CHECK-RV64 %s

Expand Down Expand Up @@ -597,3 +597,63 @@ vuint64m8_t test_vcompress_vm_u64m8(vuint64m8_t src, vbool8_t mask, size_t vl) {
return __riscv_vcompress_vm_u64m8(src, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 1 x bfloat> @test_vcompress_vm_bf16mf4
// CHECK-RV64-SAME: (<vscale x 1 x bfloat> [[SRC:%.*]], <vscale x 1 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 1 x bfloat> @llvm.riscv.vcompress.nxv1bf16.i64(<vscale x 1 x bfloat> poison, <vscale x 1 x bfloat> [[SRC]], <vscale x 1 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 1 x bfloat> [[TMP0]]
//
vbfloat16mf4_t test_vcompress_vm_bf16mf4(vbfloat16mf4_t src, vbool64_t mask, size_t vl) {
return __riscv_vcompress_vm_bf16mf4(src, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 2 x bfloat> @test_vcompress_vm_bf16mf2
// CHECK-RV64-SAME: (<vscale x 2 x bfloat> [[SRC:%.*]], <vscale x 2 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 2 x bfloat> @llvm.riscv.vcompress.nxv2bf16.i64(<vscale x 2 x bfloat> poison, <vscale x 2 x bfloat> [[SRC]], <vscale x 2 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 2 x bfloat> [[TMP0]]
//
vbfloat16mf2_t test_vcompress_vm_bf16mf2(vbfloat16mf2_t src, vbool32_t mask, size_t vl) {
return __riscv_vcompress_vm_bf16mf2(src, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 4 x bfloat> @test_vcompress_vm_bf16m1
// CHECK-RV64-SAME: (<vscale x 4 x bfloat> [[SRC:%.*]], <vscale x 4 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 4 x bfloat> @llvm.riscv.vcompress.nxv4bf16.i64(<vscale x 4 x bfloat> poison, <vscale x 4 x bfloat> [[SRC]], <vscale x 4 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 4 x bfloat> [[TMP0]]
//
vbfloat16m1_t test_vcompress_vm_bf16m1(vbfloat16m1_t src, vbool16_t mask, size_t vl) {
return __riscv_vcompress_vm_bf16m1(src, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 8 x bfloat> @test_vcompress_vm_bf16m2
// CHECK-RV64-SAME: (<vscale x 8 x bfloat> [[SRC:%.*]], <vscale x 8 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 8 x bfloat> @llvm.riscv.vcompress.nxv8bf16.i64(<vscale x 8 x bfloat> poison, <vscale x 8 x bfloat> [[SRC]], <vscale x 8 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 8 x bfloat> [[TMP0]]
//
vbfloat16m2_t test_vcompress_vm_bf16m2(vbfloat16m2_t src, vbool8_t mask, size_t vl) {
return __riscv_vcompress_vm_bf16m2(src, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 16 x bfloat> @test_vcompress_vm_bf16m4
// CHECK-RV64-SAME: (<vscale x 16 x bfloat> [[SRC:%.*]], <vscale x 16 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 16 x bfloat> @llvm.riscv.vcompress.nxv16bf16.i64(<vscale x 16 x bfloat> poison, <vscale x 16 x bfloat> [[SRC]], <vscale x 16 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 16 x bfloat> [[TMP0]]
//
vbfloat16m4_t test_vcompress_vm_bf16m4(vbfloat16m4_t src, vbool4_t mask, size_t vl) {
return __riscv_vcompress_vm_bf16m4(src, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 32 x bfloat> @test_vcompress_vm_bf16m8
// CHECK-RV64-SAME: (<vscale x 32 x bfloat> [[SRC:%.*]], <vscale x 32 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 32 x bfloat> @llvm.riscv.vcompress.nxv32bf16.i64(<vscale x 32 x bfloat> poison, <vscale x 32 x bfloat> [[SRC]], <vscale x 32 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 32 x bfloat> [[TMP0]]
//
vbfloat16m8_t test_vcompress_vm_bf16m8(vbfloat16m8_t src, vbool2_t mask, size_t vl) {
return __riscv_vcompress_vm_bf16m8(src, mask, vl);
}

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2
// REQUIRES: riscv-registered-target
// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \
// RUN: -target-feature +zvfhmin -disable-O0-optnone \
// RUN: -target-feature +zvfhmin -target-feature +zvfbfmin -disable-O0-optnone \
// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \
// RUN: FileCheck --check-prefix=CHECK-RV64 %s

Expand Down Expand Up @@ -1037,3 +1037,62 @@ vfloat64m8_t test_vmerge_vvm_f64m8(vfloat64m8_t op1, vfloat64m8_t op2, vbool8_t
return __riscv_vmerge_vvm_f64m8(op1, op2, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 1 x bfloat> @test_vmerge_vvm_bf16mf4
// CHECK-RV64-SAME: (<vscale x 1 x bfloat> [[OP1:%.*]], <vscale x 1 x bfloat> [[OP2:%.*]], <vscale x 1 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 1 x bfloat> @llvm.riscv.vmerge.nxv1bf16.nxv1bf16.i64(<vscale x 1 x bfloat> poison, <vscale x 1 x bfloat> [[OP1]], <vscale x 1 x bfloat> [[OP2]], <vscale x 1 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 1 x bfloat> [[TMP0]]
//
vbfloat16mf4_t test_vmerge_vvm_bf16mf4(vbfloat16mf4_t op1, vbfloat16mf4_t op2, vbool64_t mask, size_t vl) {
return __riscv_vmerge_vvm_bf16mf4(op1, op2, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 2 x bfloat> @test_vmerge_vvm_bf16mf2
// CHECK-RV64-SAME: (<vscale x 2 x bfloat> [[OP1:%.*]], <vscale x 2 x bfloat> [[OP2:%.*]], <vscale x 2 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 2 x bfloat> @llvm.riscv.vmerge.nxv2bf16.nxv2bf16.i64(<vscale x 2 x bfloat> poison, <vscale x 2 x bfloat> [[OP1]], <vscale x 2 x bfloat> [[OP2]], <vscale x 2 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 2 x bfloat> [[TMP0]]
//
vbfloat16mf2_t test_vmerge_vvm_bf16mf2(vbfloat16mf2_t op1, vbfloat16mf2_t op2, vbool32_t mask, size_t vl) {
return __riscv_vmerge_vvm_bf16mf2(op1, op2, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 4 x bfloat> @test_vmerge_vvm_bf16m1
// CHECK-RV64-SAME: (<vscale x 4 x bfloat> [[OP1:%.*]], <vscale x 4 x bfloat> [[OP2:%.*]], <vscale x 4 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 4 x bfloat> @llvm.riscv.vmerge.nxv4bf16.nxv4bf16.i64(<vscale x 4 x bfloat> poison, <vscale x 4 x bfloat> [[OP1]], <vscale x 4 x bfloat> [[OP2]], <vscale x 4 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 4 x bfloat> [[TMP0]]
//
vbfloat16m1_t test_vmerge_vvm_bf16m1(vbfloat16m1_t op1, vbfloat16m1_t op2, vbool16_t mask, size_t vl) {
return __riscv_vmerge_vvm_bf16m1(op1, op2, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 8 x bfloat> @test_vmerge_vvm_bf16m2
// CHECK-RV64-SAME: (<vscale x 8 x bfloat> [[OP1:%.*]], <vscale x 8 x bfloat> [[OP2:%.*]], <vscale x 8 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 8 x bfloat> @llvm.riscv.vmerge.nxv8bf16.nxv8bf16.i64(<vscale x 8 x bfloat> poison, <vscale x 8 x bfloat> [[OP1]], <vscale x 8 x bfloat> [[OP2]], <vscale x 8 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 8 x bfloat> [[TMP0]]
//
vbfloat16m2_t test_vmerge_vvm_bf16m2(vbfloat16m2_t op1, vbfloat16m2_t op2, vbool8_t mask, size_t vl) {
return __riscv_vmerge_vvm_bf16m2(op1, op2, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 16 x bfloat> @test_vmerge_vvm_bf16m4
// CHECK-RV64-SAME: (<vscale x 16 x bfloat> [[OP1:%.*]], <vscale x 16 x bfloat> [[OP2:%.*]], <vscale x 16 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 16 x bfloat> @llvm.riscv.vmerge.nxv16bf16.nxv16bf16.i64(<vscale x 16 x bfloat> poison, <vscale x 16 x bfloat> [[OP1]], <vscale x 16 x bfloat> [[OP2]], <vscale x 16 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 16 x bfloat> [[TMP0]]
//
vbfloat16m4_t test_vmerge_vvm_bf16m4(vbfloat16m4_t op1, vbfloat16m4_t op2, vbool4_t mask, size_t vl) {
return __riscv_vmerge_vvm_bf16m4(op1, op2, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 32 x bfloat> @test_vmerge_vvm_bf16m8
// CHECK-RV64-SAME: (<vscale x 32 x bfloat> [[OP1:%.*]], <vscale x 32 x bfloat> [[OP2:%.*]], <vscale x 32 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 32 x bfloat> @llvm.riscv.vmerge.nxv32bf16.nxv32bf16.i64(<vscale x 32 x bfloat> poison, <vscale x 32 x bfloat> [[OP1]], <vscale x 32 x bfloat> [[OP2]], <vscale x 32 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 32 x bfloat> [[TMP0]]
//
vbfloat16m8_t test_vmerge_vvm_bf16m8(vbfloat16m8_t op1, vbfloat16m8_t op2, vbool2_t mask, size_t vl) {
return __riscv_vmerge_vvm_bf16m8(op1, op2, mask, vl);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2
// REQUIRES: riscv-registered-target
// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \
// RUN: -target-feature +zvfhmin -disable-O0-optnone \
// RUN: -target-feature +zvfhmin -target-feature +zvfbfmin -disable-O0-optnone \
// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \
// RUN: FileCheck --check-prefix=CHECK-RV64 %s

Expand Down Expand Up @@ -1917,3 +1917,63 @@ vuint64m8_t test_vmv_s_x_u64m8(uint64_t src, size_t vl) {
return __riscv_vmv_s_x_u64m8(src, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 1 x bfloat> @test_vmv_v_v_bf16mf4
// CHECK-RV64-SAME: (<vscale x 1 x bfloat> [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 1 x bfloat> @llvm.riscv.vmv.v.v.nxv1bf16.i64(<vscale x 1 x bfloat> poison, <vscale x 1 x bfloat> [[SRC]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 1 x bfloat> [[TMP0]]
//
vbfloat16mf4_t test_vmv_v_v_bf16mf4(vbfloat16mf4_t src, size_t vl) {
return __riscv_vmv_v_v_bf16mf4(src, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 2 x bfloat> @test_vmv_v_v_bf16mf2
// CHECK-RV64-SAME: (<vscale x 2 x bfloat> [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 2 x bfloat> @llvm.riscv.vmv.v.v.nxv2bf16.i64(<vscale x 2 x bfloat> poison, <vscale x 2 x bfloat> [[SRC]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 2 x bfloat> [[TMP0]]
//
vbfloat16mf2_t test_vmv_v_v_bf16mf2(vbfloat16mf2_t src, size_t vl) {
return __riscv_vmv_v_v_bf16mf2(src, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 4 x bfloat> @test_vmv_v_v_bf16m1
// CHECK-RV64-SAME: (<vscale x 4 x bfloat> [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 4 x bfloat> @llvm.riscv.vmv.v.v.nxv4bf16.i64(<vscale x 4 x bfloat> poison, <vscale x 4 x bfloat> [[SRC]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 4 x bfloat> [[TMP0]]
//
vbfloat16m1_t test_vmv_v_v_bf16m1(vbfloat16m1_t src, size_t vl) {
return __riscv_vmv_v_v_bf16m1(src, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 8 x bfloat> @test_vmv_v_v_bf16m2
// CHECK-RV64-SAME: (<vscale x 8 x bfloat> [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 8 x bfloat> @llvm.riscv.vmv.v.v.nxv8bf16.i64(<vscale x 8 x bfloat> poison, <vscale x 8 x bfloat> [[SRC]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 8 x bfloat> [[TMP0]]
//
vbfloat16m2_t test_vmv_v_v_bf16m2(vbfloat16m2_t src, size_t vl) {
return __riscv_vmv_v_v_bf16m2(src, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 16 x bfloat> @test_vmv_v_v_bf16m4
// CHECK-RV64-SAME: (<vscale x 16 x bfloat> [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 16 x bfloat> @llvm.riscv.vmv.v.v.nxv16bf16.i64(<vscale x 16 x bfloat> poison, <vscale x 16 x bfloat> [[SRC]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 16 x bfloat> [[TMP0]]
//
vbfloat16m4_t test_vmv_v_v_bf16m4(vbfloat16m4_t src, size_t vl) {
return __riscv_vmv_v_v_bf16m4(src, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 32 x bfloat> @test_vmv_v_v_bf16m8
// CHECK-RV64-SAME: (<vscale x 32 x bfloat> [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 32 x bfloat> @llvm.riscv.vmv.v.v.nxv32bf16.i64(<vscale x 32 x bfloat> poison, <vscale x 32 x bfloat> [[SRC]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 32 x bfloat> [[TMP0]]
//
vbfloat16m8_t test_vmv_v_v_bf16m8(vbfloat16m8_t src, size_t vl) {
return __riscv_vmv_v_v_bf16m8(src, vl);
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2
// REQUIRES: riscv-registered-target
// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \
// RUN: -target-feature +zvfh -disable-O0-optnone \
// RUN: -target-feature +zvfhmin -target-feature +zvfbfmin -disable-O0-optnone \
// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \
// RUN: FileCheck --check-prefix=CHECK-RV64 %s

Expand Down Expand Up @@ -597,3 +597,63 @@ vuint64m8_t test_vcompress_vm_u64m8(vuint64m8_t src, vbool8_t mask, size_t vl) {
return __riscv_vcompress(src, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 1 x bfloat> @test_vcompress_vm_bf16mf4
// CHECK-RV64-SAME: (<vscale x 1 x bfloat> [[SRC:%.*]], <vscale x 1 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 1 x bfloat> @llvm.riscv.vcompress.nxv1bf16.i64(<vscale x 1 x bfloat> poison, <vscale x 1 x bfloat> [[SRC]], <vscale x 1 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 1 x bfloat> [[TMP0]]
//
vbfloat16mf4_t test_vcompress_vm_bf16mf4(vbfloat16mf4_t src, vbool64_t mask, size_t vl) {
return __riscv_vcompress(src, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 2 x bfloat> @test_vcompress_vm_bf16mf2
// CHECK-RV64-SAME: (<vscale x 2 x bfloat> [[SRC:%.*]], <vscale x 2 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 2 x bfloat> @llvm.riscv.vcompress.nxv2bf16.i64(<vscale x 2 x bfloat> poison, <vscale x 2 x bfloat> [[SRC]], <vscale x 2 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 2 x bfloat> [[TMP0]]
//
vbfloat16mf2_t test_vcompress_vm_bf16mf2(vbfloat16mf2_t src, vbool32_t mask, size_t vl) {
return __riscv_vcompress(src, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 4 x bfloat> @test_vcompress_vm_bf16m1
// CHECK-RV64-SAME: (<vscale x 4 x bfloat> [[SRC:%.*]], <vscale x 4 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 4 x bfloat> @llvm.riscv.vcompress.nxv4bf16.i64(<vscale x 4 x bfloat> poison, <vscale x 4 x bfloat> [[SRC]], <vscale x 4 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 4 x bfloat> [[TMP0]]
//
vbfloat16m1_t test_vcompress_vm_bf16m1(vbfloat16m1_t src, vbool16_t mask, size_t vl) {
return __riscv_vcompress(src, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 8 x bfloat> @test_vcompress_vm_bf16m2
// CHECK-RV64-SAME: (<vscale x 8 x bfloat> [[SRC:%.*]], <vscale x 8 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 8 x bfloat> @llvm.riscv.vcompress.nxv8bf16.i64(<vscale x 8 x bfloat> poison, <vscale x 8 x bfloat> [[SRC]], <vscale x 8 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 8 x bfloat> [[TMP0]]
//
vbfloat16m2_t test_vcompress_vm_bf16m2(vbfloat16m2_t src, vbool8_t mask, size_t vl) {
return __riscv_vcompress(src, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 16 x bfloat> @test_vcompress_vm_bf16m4
// CHECK-RV64-SAME: (<vscale x 16 x bfloat> [[SRC:%.*]], <vscale x 16 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 16 x bfloat> @llvm.riscv.vcompress.nxv16bf16.i64(<vscale x 16 x bfloat> poison, <vscale x 16 x bfloat> [[SRC]], <vscale x 16 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 16 x bfloat> [[TMP0]]
//
vbfloat16m4_t test_vcompress_vm_bf16m4(vbfloat16m4_t src, vbool4_t mask, size_t vl) {
return __riscv_vcompress(src, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 32 x bfloat> @test_vcompress_vm_bf16m8
// CHECK-RV64-SAME: (<vscale x 32 x bfloat> [[SRC:%.*]], <vscale x 32 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 32 x bfloat> @llvm.riscv.vcompress.nxv32bf16.i64(<vscale x 32 x bfloat> poison, <vscale x 32 x bfloat> [[SRC]], <vscale x 32 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 32 x bfloat> [[TMP0]]
//
vbfloat16m8_t test_vcompress_vm_bf16m8(vbfloat16m8_t src, vbool2_t mask, size_t vl) {
return __riscv_vcompress(src, mask, vl);
}

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2
// REQUIRES: riscv-registered-target
// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \
// RUN: -target-feature +zvfhmin -disable-O0-optnone \
// RUN: -target-feature +zvfhmin -target-feature +zvfbfmin -disable-O0-optnone \
// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \
// RUN: FileCheck --check-prefix=CHECK-RV64 %s

Expand Down Expand Up @@ -1037,3 +1037,63 @@ vfloat64m8_t test_vmerge_vvm_f64m8(vfloat64m8_t op1, vfloat64m8_t op2, vbool8_t
return __riscv_vmerge(op1, op2, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 1 x bfloat> @test_vmerge_vvm_bf16mf4
// CHECK-RV64-SAME: (<vscale x 1 x bfloat> [[OP1:%.*]], <vscale x 1 x bfloat> [[OP2:%.*]], <vscale x 1 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 1 x bfloat> @llvm.riscv.vmerge.nxv1bf16.nxv1bf16.i64(<vscale x 1 x bfloat> poison, <vscale x 1 x bfloat> [[OP1]], <vscale x 1 x bfloat> [[OP2]], <vscale x 1 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 1 x bfloat> [[TMP0]]
//
vbfloat16mf4_t test_vmerge_vvm_bf16mf4(vbfloat16mf4_t op1, vbfloat16mf4_t op2, vbool64_t mask, size_t vl) {
return __riscv_vmerge(op1, op2, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 2 x bfloat> @test_vmerge_vvm_bf16mf2
// CHECK-RV64-SAME: (<vscale x 2 x bfloat> [[OP1:%.*]], <vscale x 2 x bfloat> [[OP2:%.*]], <vscale x 2 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 2 x bfloat> @llvm.riscv.vmerge.nxv2bf16.nxv2bf16.i64(<vscale x 2 x bfloat> poison, <vscale x 2 x bfloat> [[OP1]], <vscale x 2 x bfloat> [[OP2]], <vscale x 2 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 2 x bfloat> [[TMP0]]
//
vbfloat16mf2_t test_vmerge_vvm_bf16mf2(vbfloat16mf2_t op1, vbfloat16mf2_t op2, vbool32_t mask, size_t vl) {
return __riscv_vmerge(op1, op2, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 4 x bfloat> @test_vmerge_vvm_bf16m1
// CHECK-RV64-SAME: (<vscale x 4 x bfloat> [[OP1:%.*]], <vscale x 4 x bfloat> [[OP2:%.*]], <vscale x 4 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 4 x bfloat> @llvm.riscv.vmerge.nxv4bf16.nxv4bf16.i64(<vscale x 4 x bfloat> poison, <vscale x 4 x bfloat> [[OP1]], <vscale x 4 x bfloat> [[OP2]], <vscale x 4 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 4 x bfloat> [[TMP0]]
//
vbfloat16m1_t test_vmerge_vvm_bf16m1(vbfloat16m1_t op1, vbfloat16m1_t op2, vbool16_t mask, size_t vl) {
return __riscv_vmerge(op1, op2, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 8 x bfloat> @test_vmerge_vvm_bf16m2
// CHECK-RV64-SAME: (<vscale x 8 x bfloat> [[OP1:%.*]], <vscale x 8 x bfloat> [[OP2:%.*]], <vscale x 8 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 8 x bfloat> @llvm.riscv.vmerge.nxv8bf16.nxv8bf16.i64(<vscale x 8 x bfloat> poison, <vscale x 8 x bfloat> [[OP1]], <vscale x 8 x bfloat> [[OP2]], <vscale x 8 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 8 x bfloat> [[TMP0]]
//
vbfloat16m2_t test_vmerge_vvm_bf16m2(vbfloat16m2_t op1, vbfloat16m2_t op2, vbool8_t mask, size_t vl) {
return __riscv_vmerge(op1, op2, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 16 x bfloat> @test_vmerge_vvm_bf16m4
// CHECK-RV64-SAME: (<vscale x 16 x bfloat> [[OP1:%.*]], <vscale x 16 x bfloat> [[OP2:%.*]], <vscale x 16 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 16 x bfloat> @llvm.riscv.vmerge.nxv16bf16.nxv16bf16.i64(<vscale x 16 x bfloat> poison, <vscale x 16 x bfloat> [[OP1]], <vscale x 16 x bfloat> [[OP2]], <vscale x 16 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 16 x bfloat> [[TMP0]]
//
vbfloat16m4_t test_vmerge_vvm_bf16m4(vbfloat16m4_t op1, vbfloat16m4_t op2, vbool4_t mask, size_t vl) {
return __riscv_vmerge(op1, op2, mask, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 32 x bfloat> @test_vmerge_vvm_bf16m8
// CHECK-RV64-SAME: (<vscale x 32 x bfloat> [[OP1:%.*]], <vscale x 32 x bfloat> [[OP2:%.*]], <vscale x 32 x i1> [[MASK:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 32 x bfloat> @llvm.riscv.vmerge.nxv32bf16.nxv32bf16.i64(<vscale x 32 x bfloat> poison, <vscale x 32 x bfloat> [[OP1]], <vscale x 32 x bfloat> [[OP2]], <vscale x 32 x i1> [[MASK]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 32 x bfloat> [[TMP0]]
//
vbfloat16m8_t test_vmerge_vvm_bf16m8(vbfloat16m8_t op1, vbfloat16m8_t op2, vbool2_t mask, size_t vl) {
return __riscv_vmerge(op1, op2, mask, vl);
}

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2
// REQUIRES: riscv-registered-target
// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh \
// RUN: -target-feature +zvfhmin -disable-O0-optnone \
// RUN: -target-feature +zvfhmin -target-feature +zvfbfmin -disable-O0-optnone \
// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \
// RUN: FileCheck --check-prefix=CHECK-RV64 %s

Expand Down Expand Up @@ -1037,3 +1037,63 @@ uint64_t test_vmv_x_s_u64m8_u64(vuint64m8_t src) {
return __riscv_vmv_x(src);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 1 x bfloat> @test_vmv_v_v_bf16mf4
// CHECK-RV64-SAME: (<vscale x 1 x bfloat> [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 1 x bfloat> @llvm.riscv.vmv.v.v.nxv1bf16.i64(<vscale x 1 x bfloat> poison, <vscale x 1 x bfloat> [[SRC]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 1 x bfloat> [[TMP0]]
//
vbfloat16mf4_t test_vmv_v_v_bf16mf4(vbfloat16mf4_t src, size_t vl) {
return __riscv_vmv_v(src, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 2 x bfloat> @test_vmv_v_v_bf16mf2
// CHECK-RV64-SAME: (<vscale x 2 x bfloat> [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 2 x bfloat> @llvm.riscv.vmv.v.v.nxv2bf16.i64(<vscale x 2 x bfloat> poison, <vscale x 2 x bfloat> [[SRC]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 2 x bfloat> [[TMP0]]
//
vbfloat16mf2_t test_vmv_v_v_bf16mf2(vbfloat16mf2_t src, size_t vl) {
return __riscv_vmv_v(src, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 4 x bfloat> @test_vmv_v_v_bf16m1
// CHECK-RV64-SAME: (<vscale x 4 x bfloat> [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 4 x bfloat> @llvm.riscv.vmv.v.v.nxv4bf16.i64(<vscale x 4 x bfloat> poison, <vscale x 4 x bfloat> [[SRC]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 4 x bfloat> [[TMP0]]
//
vbfloat16m1_t test_vmv_v_v_bf16m1(vbfloat16m1_t src, size_t vl) {
return __riscv_vmv_v(src, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 8 x bfloat> @test_vmv_v_v_bf16m2
// CHECK-RV64-SAME: (<vscale x 8 x bfloat> [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 8 x bfloat> @llvm.riscv.vmv.v.v.nxv8bf16.i64(<vscale x 8 x bfloat> poison, <vscale x 8 x bfloat> [[SRC]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 8 x bfloat> [[TMP0]]
//
vbfloat16m2_t test_vmv_v_v_bf16m2(vbfloat16m2_t src, size_t vl) {
return __riscv_vmv_v(src, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 16 x bfloat> @test_vmv_v_v_bf16m4
// CHECK-RV64-SAME: (<vscale x 16 x bfloat> [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 16 x bfloat> @llvm.riscv.vmv.v.v.nxv16bf16.i64(<vscale x 16 x bfloat> poison, <vscale x 16 x bfloat> [[SRC]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 16 x bfloat> [[TMP0]]
//
vbfloat16m4_t test_vmv_v_v_bf16m4(vbfloat16m4_t src, size_t vl) {
return __riscv_vmv_v(src, vl);
}

// CHECK-RV64-LABEL: define dso_local <vscale x 32 x bfloat> @test_vmv_v_v_bf16m8
// CHECK-RV64-SAME: (<vscale x 32 x bfloat> [[SRC:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] {
// CHECK-RV64-NEXT: entry:
// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 32 x bfloat> @llvm.riscv.vmv.v.v.nxv32bf16.i64(<vscale x 32 x bfloat> poison, <vscale x 32 x bfloat> [[SRC]], i64 [[VL]])
// CHECK-RV64-NEXT: ret <vscale x 32 x bfloat> [[TMP0]]
//
vbfloat16m8_t test_vmv_v_v_bf16m8(vbfloat16m8_t src, size_t vl) {
return __riscv_vmv_v(src, vl);
}

Loading